OSDN Git Service

Please enter the commit message for your changes. Lines starting
[eos/base.git] / util / src / TclTk / tk8.6.12 / generic / tkImgPhInstance.c
1 /*
2  * tkImgPhInstance.c --
3  *
4  *      Implements the rendering of images of type "photo" for Tk. Photo
5  *      images are stored in full color (32 bits per pixel including alpha
6  *      channel) and displayed using dithering if necessary.
7  *
8  * Copyright (c) 1994 The Australian National University.
9  * Copyright (c) 1994-1997 Sun Microsystems, Inc.
10  * Copyright (c) 2002-2008 Donal K. Fellows
11  * Copyright (c) 2003 ActiveState Corporation.
12  *
13  * See the file "license.terms" for information on usage and redistribution of
14  * this file, and for a DISCLAIMER OF ALL WARRANTIES.
15  *
16  * Author: Paul Mackerras (paulus@cs.anu.edu.au),
17  *         Department of Computer Science,
18  *         Australian National University.
19  */
20
21 #include "tkImgPhoto.h"
22 #include "tkPort.h"
23
24 /*
25  * Declaration for internal Xlib function used here:
26  */
27
28 extern int              _XInitImageFuncPtrs(XImage *image);
29
30 /*
31  * Forward declarations
32  */
33
34 #ifndef TK_CAN_RENDER_RGBA
35 static void             BlendComplexAlpha(XImage *bgImg, PhotoInstance *iPtr,
36                             int xOffset, int yOffset, int width, int height);
37 #endif
38 static int              IsValidPalette(PhotoInstance *instancePtr,
39                             const char *palette);
40 static int              CountBits(pixel mask);
41 static void             GetColorTable(PhotoInstance *instancePtr);
42 static void             FreeColorTable(ColorTable *colorPtr, int force);
43 static void             AllocateColors(ColorTable *colorPtr);
44 static void             DisposeColorTable(ClientData clientData);
45 static int              ReclaimColors(ColorTableId *id, int numColors);
46
47 /*
48  * Hash table used to hash from (display, colormap, palette, gamma) to
49  * ColorTable address.
50  */
51
52 static Tcl_HashTable imgPhotoColorHash;
53 static int imgPhotoColorHashInitialized;
54 #define N_COLOR_HASH    (sizeof(ColorTableId) / sizeof(int))
55 \f
56 /*
57  *----------------------------------------------------------------------
58  *
59  * TkImgPhotoConfigureInstance --
60  *
61  *      This function is called to create displaying information for a photo
62  *      image instance based on the configuration information in the model.
63  *      It is invoked both when new instances are created and when the model
64  *      is reconfigured.
65  *
66  * Results:
67  *      None.
68  *
69  * Side effects:
70  *      Generates errors via Tcl_BackgroundException if there are problems in
71  *      setting up the instance.
72  *
73  *----------------------------------------------------------------------
74  */
75
76 void
77 TkImgPhotoConfigureInstance(
78     PhotoInstance *instancePtr) /* Instance to reconfigure. */
79 {
80     PhotoModel *modelPtr = instancePtr->masterPtr;
81     XImage *imagePtr;
82     int bitsPerPixel;
83     ColorTable *colorTablePtr;
84     XRectangle validBox;
85
86     /*
87      * If the -palette configuration option has been set for the model, use
88      * the value specified for our palette, but only if it is a valid palette
89      * for our windows. Use the gamma value specified the model.
90      */
91
92     if ((modelPtr->palette && modelPtr->palette[0])
93             && IsValidPalette(instancePtr, modelPtr->palette)) {
94         instancePtr->palette = modelPtr->palette;
95     } else {
96         instancePtr->palette = instancePtr->defaultPalette;
97     }
98     instancePtr->gamma = modelPtr->gamma;
99
100     /*
101      * If we don't currently have a color table, or if the one we have no
102      * longer applies (e.g. because our palette or gamma has changed), get a
103      * new one.
104      */
105
106     colorTablePtr = instancePtr->colorTablePtr;
107     if ((colorTablePtr == NULL)
108             || (instancePtr->colormap != colorTablePtr->id.colormap)
109             || (instancePtr->palette != colorTablePtr->id.palette)
110             || (instancePtr->gamma != colorTablePtr->id.gamma)) {
111         /*
112          * Free up our old color table, and get a new one.
113          */
114
115         if (colorTablePtr != NULL) {
116             colorTablePtr->liveRefCount -= 1;
117             FreeColorTable(colorTablePtr, 0);
118         }
119         GetColorTable(instancePtr);
120
121         /*
122          * Create a new XImage structure for sending data to the X server, if
123          * necessary.
124          */
125
126         if (instancePtr->colorTablePtr->flags & BLACK_AND_WHITE) {
127             bitsPerPixel = 1;
128         } else {
129             bitsPerPixel = instancePtr->visualInfo.depth;
130         }
131
132         if ((instancePtr->imagePtr == NULL)
133                 || (instancePtr->imagePtr->bits_per_pixel != bitsPerPixel)) {
134             if (instancePtr->imagePtr != NULL) {
135                 XDestroyImage(instancePtr->imagePtr);
136             }
137             imagePtr = XCreateImage(instancePtr->display,
138                     instancePtr->visualInfo.visual, (unsigned) bitsPerPixel,
139                     (bitsPerPixel > 1? ZPixmap: XYBitmap), 0, NULL,
140                     1, 1, 32, 0);
141             instancePtr->imagePtr = imagePtr;
142
143             /*
144              * We create images using the local host's endianness, rather than
145              * the endianness of the server; otherwise we would have to
146              * byte-swap any 16 or 32 bit values that we store in the image
147              * if the server's endianness is different from ours.
148              */
149
150             if (imagePtr != NULL) {
151 #ifdef WORDS_BIGENDIAN
152                 imagePtr->byte_order = MSBFirst;
153 #else
154                 imagePtr->byte_order = LSBFirst;
155 #endif
156                 _XInitImageFuncPtrs(imagePtr);
157             }
158         }
159     }
160
161     /*
162      * If the user has specified a width and/or height for the model which is
163      * different from our current width/height, set the size to the values
164      * specified by the user. If we have no pixmap, we do this also, since it
165      * has the side effect of allocating a pixmap for us.
166      */
167
168     if ((instancePtr->pixels == None) || (instancePtr->error == NULL)
169             || (instancePtr->width != modelPtr->width)
170             || (instancePtr->height != modelPtr->height)) {
171         TkImgPhotoInstanceSetSize(instancePtr);
172     }
173
174     /*
175      * Redither this instance if necessary.
176      */
177
178     if ((modelPtr->flags & IMAGE_CHANGED)
179             || (instancePtr->colorTablePtr != colorTablePtr)) {
180         TkClipBox(modelPtr->validRegion, &validBox);
181         if ((validBox.width > 0) && (validBox.height > 0)) {
182             TkImgDitherInstance(instancePtr, validBox.x, validBox.y,
183                     validBox.width, validBox.height);
184         }
185     }
186 }
187 \f
188 /*
189  *----------------------------------------------------------------------
190  *
191  * TkImgPhotoGet --
192  *
193  *      This function is called for each use of a photo image in a widget.
194  *
195  * Results:
196  *      The return value is a token for the instance, which is passed back to
197  *      us in calls to TkImgPhotoDisplay and ImgPhotoFree.
198  *
199  * Side effects:
200  *      A data structure is set up for the instance (or, an existing instance
201  *      is re-used for the new one).
202  *
203  *----------------------------------------------------------------------
204  */
205
206 ClientData
207 TkImgPhotoGet(
208     Tk_Window tkwin,            /* Window in which the instance will be
209                                  * used. */
210     ClientData modelData)       /* Pointer to our model structure for the
211                                  * image. */
212 {
213     PhotoModel *modelPtr = modelData;
214     PhotoInstance *instancePtr;
215     Colormap colormap;
216     int mono, nRed, nGreen, nBlue, numVisuals;
217     XVisualInfo visualInfo, *visInfoPtr;
218     char buf[TCL_INTEGER_SPACE * 3];
219     XColor *white, *black;
220     XGCValues gcValues;
221
222     /*
223      * Table of "best" choices for palette for PseudoColor displays with
224      * between 3 and 15 bits/pixel.
225      */
226
227     static const int paletteChoice[13][3] = {
228         /*  #red, #green, #blue */
229          {2,  2,  2,            /* 3 bits, 8 colors */},
230          {2,  3,  2,            /* 4 bits, 12 colors */},
231          {3,  4,  2,            /* 5 bits, 24 colors */},
232          {4,  5,  3,            /* 6 bits, 60 colors */},
233          {5,  6,  4,            /* 7 bits, 120 colors */},
234          {7,  7,  4,            /* 8 bits, 198 colors */},
235          {8, 10,  6,            /* 9 bits, 480 colors */},
236         {10, 12,  8,            /* 10 bits, 960 colors */},
237         {14, 15,  9,            /* 11 bits, 1890 colors */},
238         {16, 20, 12,            /* 12 bits, 3840 colors */},
239         {20, 24, 16,            /* 13 bits, 7680 colors */},
240         {26, 30, 20,            /* 14 bits, 15600 colors */},
241         {32, 32, 30,            /* 15 bits, 30720 colors */}
242     };
243
244     /*
245      * See if there is already an instance for windows using the same
246      * colormap. If so then just re-use it.
247      */
248
249     colormap = Tk_Colormap(tkwin);
250     for (instancePtr = modelPtr->instancePtr; instancePtr != NULL;
251             instancePtr = instancePtr->nextPtr) {
252         if ((colormap == instancePtr->colormap)
253                 && (Tk_Display(tkwin) == instancePtr->display)) {
254             /*
255              * Re-use this instance.
256              */
257
258             if (instancePtr->refCount == 0) {
259                 /*
260                  * We are resurrecting this instance.
261                  */
262
263                 Tcl_CancelIdleCall(TkImgDisposeInstance, instancePtr);
264                 if (instancePtr->colorTablePtr != NULL) {
265                     FreeColorTable(instancePtr->colorTablePtr, 0);
266                 }
267                 GetColorTable(instancePtr);
268             }
269             instancePtr->refCount++;
270             return instancePtr;
271         }
272     }
273
274     /*
275      * The image isn't already in use in a window with the same colormap. Make
276      * a new instance of the image.
277      */
278
279     instancePtr = ckalloc(sizeof(PhotoInstance));
280     instancePtr->masterPtr = modelPtr;
281     instancePtr->display = Tk_Display(tkwin);
282     instancePtr->colormap = Tk_Colormap(tkwin);
283     Tk_PreserveColormap(instancePtr->display, instancePtr->colormap);
284     instancePtr->refCount = 1;
285     instancePtr->colorTablePtr = NULL;
286     instancePtr->pixels = None;
287     instancePtr->error = NULL;
288     instancePtr->width = 0;
289     instancePtr->height = 0;
290     instancePtr->imagePtr = 0;
291     instancePtr->nextPtr = modelPtr->instancePtr;
292     modelPtr->instancePtr = instancePtr;
293
294     /*
295      * Obtain information about the visual and decide on the default palette.
296      */
297
298     visualInfo.screen = Tk_ScreenNumber(tkwin);
299     visualInfo.visualid = XVisualIDFromVisual(Tk_Visual(tkwin));
300     visInfoPtr = XGetVisualInfo(Tk_Display(tkwin),
301             VisualScreenMask | VisualIDMask, &visualInfo, &numVisuals);
302     if (visInfoPtr == NULL) {
303         Tcl_Panic("TkImgPhotoGet couldn't find visual for window");
304     }
305
306     nRed = 2;
307     nGreen = nBlue = 0;
308     mono = 1;
309     instancePtr->visualInfo = *visInfoPtr;
310     switch (visInfoPtr->c_class) {
311     case DirectColor:
312     case TrueColor:
313         nRed = 1 << CountBits(visInfoPtr->red_mask);
314         nGreen = 1 << CountBits(visInfoPtr->green_mask);
315         nBlue = 1 << CountBits(visInfoPtr->blue_mask);
316         mono = 0;
317         break;
318     case PseudoColor:
319     case StaticColor:
320         if (visInfoPtr->depth > 15) {
321             nRed = 32;
322             nGreen = 32;
323             nBlue = 32;
324             mono = 0;
325         } else if (visInfoPtr->depth >= 3) {
326             const int *ip = paletteChoice[visInfoPtr->depth - 3];
327
328             nRed = ip[0];
329             nGreen = ip[1];
330             nBlue = ip[2];
331             mono = 0;
332         }
333         break;
334     case GrayScale:
335     case StaticGray:
336         nRed = 1 << visInfoPtr->depth;
337         break;
338     }
339     XFree((char *) visInfoPtr);
340
341     if (mono) {
342         sprintf(buf, "%d", nRed);
343     } else {
344         sprintf(buf, "%d/%d/%d", nRed, nGreen, nBlue);
345     }
346     instancePtr->defaultPalette = Tk_GetUid(buf);
347
348     /*
349      * Make a GC with background = black and foreground = white.
350      */
351
352     white = Tk_GetColor(modelPtr->interp, tkwin, "white");
353     black = Tk_GetColor(modelPtr->interp, tkwin, "black");
354     gcValues.foreground = (white != NULL)? white->pixel:
355             WhitePixelOfScreen(Tk_Screen(tkwin));
356     gcValues.background = (black != NULL)? black->pixel:
357             BlackPixelOfScreen(Tk_Screen(tkwin));
358     Tk_FreeColor(white);
359     Tk_FreeColor(black);
360     gcValues.graphics_exposures = False;
361     instancePtr->gc = Tk_GetGC(tkwin,
362             GCForeground|GCBackground|GCGraphicsExposures, &gcValues);
363
364     /*
365      * Set configuration options and finish the initialization of the
366      * instance. This will also dither the image if necessary.
367      */
368
369     TkImgPhotoConfigureInstance(instancePtr);
370
371     /*
372      * If this is the first instance, must set the size of the image.
373      */
374
375     if (instancePtr->nextPtr == NULL) {
376         Tk_ImageChanged(modelPtr->tkMaster, 0, 0, 0, 0,
377                 modelPtr->width, modelPtr->height);
378     }
379
380     return instancePtr;
381 }
382 \f
383 /*
384  *----------------------------------------------------------------------
385  *
386  * BlendComplexAlpha --
387  *
388  *      This function is called when an image with partially transparent
389  *      pixels must be drawn over another image. It blends the photo data onto
390  *      a local copy of the surface that we are drawing on, *including* the
391  *      pixels drawn by everything that should be drawn underneath the image.
392  *
393  *      Much of this code has hard-coded values in for speed because this
394  *      routine is performance critical for complex image drawing.
395  *
396  * Results:
397  *      None.
398  *
399  * Side effects:
400  *      Background image passed in gets drawn over with image data.
401  *
402  * Notes:
403  *      This should work on all platforms that set mask and shift data
404  *      properly from the visualInfo. RGB is really only a 24+ bpp version
405  *      whereas RGB15 is the correct version and works for 15bpp+, but it
406  *      slower, so it's only used for 15bpp+.
407  *
408  *      Note that Win32 pre-defines those operations that we really need.
409  *
410  *----------------------------------------------------------------------
411  */
412 #ifndef TK_CAN_RENDER_RGBA
413 #ifndef _WIN32
414 #define GetRValue(rgb)  (UCHAR(((rgb) & red_mask) >> red_shift))
415 #define GetGValue(rgb)  (UCHAR(((rgb) & green_mask) >> green_shift))
416 #define GetBValue(rgb)  (UCHAR(((rgb) & blue_mask) >> blue_shift))
417 #define RGB(r, g, b)    ((unsigned)( \
418         (UCHAR(r) << red_shift)   | \
419         (UCHAR(g) << green_shift) | \
420         (UCHAR(b) << blue_shift)  ))
421 #define RGB15(r, g, b)  ((unsigned)( \
422         (((r) * red_mask / 255)   & red_mask)   | \
423         (((g) * green_mask / 255) & green_mask) | \
424         (((b) * blue_mask / 255)  & blue_mask)  ))
425 #endif /* !_WIN32 */
426
427 static void
428 BlendComplexAlpha(
429     XImage *bgImg,              /* Background image to draw on. */
430     PhotoInstance *iPtr,        /* Image instance to draw. */
431     int xOffset, int yOffset,   /* X & Y offset into image instance to
432                                  * draw. */
433     int width, int height)      /* Width & height of image to draw. */
434 {
435     int x, y, line;
436     unsigned long pixel;
437     unsigned char r, g, b, alpha, unalpha, *modelPtr;
438     unsigned char *alphaAr = iPtr->masterPtr->pix32;
439
440     /*
441      * This blending is an integer version of the Source-Over compositing rule
442      * (see Porter&Duff, "Compositing Digital Images", proceedings of SIGGRAPH
443      * 1984) that has been hard-coded (for speed) to work with targetting a
444      * solid surface.
445      *
446      * The 'unalpha' field must be 255-alpha; it is separated out to encourage
447      * more efficient compilation.
448      */
449
450 #define ALPHA_BLEND(bgPix, imgPix, alpha, unalpha) \
451         ((bgPix * unalpha + imgPix * alpha) / 255)
452
453     /*
454      * We have to get the mask and shift info from the visual on non-Win32 so
455      * that the macros Get*Value(), RGB() and RGB15() work correctly. This
456      * might be cached for better performance.
457      */
458
459 #ifndef _WIN32
460     unsigned long red_mask, green_mask, blue_mask;
461     unsigned long red_shift, green_shift, blue_shift;
462     Visual *visual = iPtr->visualInfo.visual;
463
464     red_mask = visual->red_mask;
465     green_mask = visual->green_mask;
466     blue_mask = visual->blue_mask;
467     red_shift = 0;
468     green_shift = 0;
469     blue_shift = 0;
470     while ((0x0001 & (red_mask >> red_shift)) == 0) {
471         red_shift++;
472     }
473     while ((0x0001 & (green_mask >> green_shift)) == 0) {
474         green_shift++;
475     }
476     while ((0x0001 & (blue_mask >> blue_shift)) == 0) {
477         blue_shift++;
478     }
479 #endif /* !_WIN32 */
480
481     /*
482      * Only UNIX requires the special case for <24bpp. It varies with 3 extra
483      * shifts and uses RGB15. The 24+bpp version could also then be further
484      * optimized.
485      */
486
487 #if !defined(_WIN32)
488     if (bgImg->depth < 24) {
489         unsigned char red_mlen, green_mlen, blue_mlen;
490
491         red_mlen = 8 - CountBits(red_mask >> red_shift);
492         green_mlen = 8 - CountBits(green_mask >> green_shift);
493         blue_mlen = 8 - CountBits(blue_mask >> blue_shift);
494         for (y = 0; y < height; y++) {
495             line = (y + yOffset) * iPtr->masterPtr->width;
496             for (x = 0; x < width; x++) {
497                 modelPtr = alphaAr + ((line + x + xOffset) * 4);
498                 alpha = modelPtr[3];
499
500                 /*
501                  * Ignore pixels that are fully transparent
502                  */
503
504                 if (alpha) {
505                     /*
506                      * We could perhaps be more efficient than XGetPixel for
507                      * 24 and 32 bit displays, but this seems "fast enough".
508                      */
509
510                     r = modelPtr[0];
511                     g = modelPtr[1];
512                     b = modelPtr[2];
513                     if (alpha != 255) {
514                         /*
515                          * Only blend pixels that have some transparency
516                          */
517
518                         unsigned char ra, ga, ba;
519
520                         pixel = XGetPixel(bgImg, x, y);
521                         ra = GetRValue(pixel) << red_mlen;
522                         ga = GetGValue(pixel) << green_mlen;
523                         ba = GetBValue(pixel) << blue_mlen;
524                         unalpha = 255 - alpha;  /* Calculate once. */
525                         r = ALPHA_BLEND(ra, r, alpha, unalpha);
526                         g = ALPHA_BLEND(ga, g, alpha, unalpha);
527                         b = ALPHA_BLEND(ba, b, alpha, unalpha);
528                     }
529                     XPutPixel(bgImg, x, y, RGB15(r, g, b));
530                 }
531             }
532         }
533         return;
534     }
535 #endif /* !_WIN32 */
536
537     for (y = 0; y < height; y++) {
538         line = (y + yOffset) * iPtr->masterPtr->width;
539         for (x = 0; x < width; x++) {
540             modelPtr = alphaAr + ((line + x + xOffset) * 4);
541             alpha = modelPtr[3];
542
543             /*
544              * Ignore pixels that are fully transparent
545              */
546
547             if (alpha) {
548                 /*
549                  * We could perhaps be more efficient than XGetPixel for 24
550                  * and 32 bit displays, but this seems "fast enough".
551                  */
552
553                 r = modelPtr[0];
554                 g = modelPtr[1];
555                 b = modelPtr[2];
556                 if (alpha != 255) {
557                     /*
558                      * Only blend pixels that have some transparency
559                      */
560
561                     unsigned char ra, ga, ba;
562
563                     pixel = XGetPixel(bgImg, x, y);
564                     ra = GetRValue(pixel);
565                     ga = GetGValue(pixel);
566                     ba = GetBValue(pixel);
567                     unalpha = 255 - alpha;      /* Calculate once. */
568                     r = ALPHA_BLEND(ra, r, alpha, unalpha);
569                     g = ALPHA_BLEND(ga, g, alpha, unalpha);
570                     b = ALPHA_BLEND(ba, b, alpha, unalpha);
571                 }
572                 XPutPixel(bgImg, x, y, RGB(r, g, b));
573             }
574         }
575     }
576 #undef ALPHA_BLEND
577 }
578 #endif /* TK_CAN_RENDER_RGBA */
579 \f
580 /*
581  *----------------------------------------------------------------------
582  *
583  * TkImgPhotoDisplay --
584  *
585  *      This function is invoked to draw a photo image.
586  *
587  * Results:
588  *      None.
589  *
590  * Side effects:
591  *      A portion of the image gets rendered in a pixmap or window.
592  *
593  *----------------------------------------------------------------------
594  */
595
596 void
597 TkImgPhotoDisplay(
598     ClientData clientData,      /* Pointer to PhotoInstance structure for
599                                  * instance to be displayed. */
600     Display *display,           /* Display on which to draw image. */
601     Drawable drawable,          /* Pixmap or window in which to draw image. */
602     int imageX, int imageY,     /* Upper-left corner of region within image to
603                                  * draw. */
604     int width, int height,      /* Dimensions of region within image to
605                                  * draw. */
606     int drawableX,int drawableY)/* Coordinates within drawable that correspond
607                                  * to imageX and imageY. */
608 {
609     PhotoInstance *instancePtr = clientData;
610 #ifndef TK_CAN_RENDER_RGBA
611     XVisualInfo visInfo = instancePtr->visualInfo;
612 #endif
613
614     /*
615      * If there's no pixmap, it means that an error occurred while creating
616      * the image instance so it can't be displayed.
617      */
618
619     if (instancePtr->pixels == None) {
620         return;
621     }
622
623 #ifdef TK_CAN_RENDER_RGBA
624
625     /*
626      * We can use TkpPutRGBAImage to render RGBA Ximages directly so there is
627      * no need to call XGetImage or to do the Porter-Duff compositing by hand.
628      */
629
630     unsigned char *rgbaPixels = instancePtr->masterPtr->pix32;
631     XImage *photo = XCreateImage(display, NULL, 32, ZPixmap, 0, (char*)rgbaPixels,
632                                  (unsigned int)instancePtr->width,
633                                  (unsigned int)instancePtr->height,
634                                  0, (unsigned int)(4 * instancePtr->width));
635     TkpPutRGBAImage(display, drawable, instancePtr->gc,
636                photo, imageX, imageY, drawableX, drawableY,
637                (unsigned int) width, (unsigned int) height);
638     photo->data = NULL;
639     XDestroyImage(photo);
640
641 #else
642
643     if ((instancePtr->masterPtr->flags & COMPLEX_ALPHA)
644             && visInfo.depth >= 15
645             && (visInfo.c_class == DirectColor || visInfo.c_class == TrueColor)) {
646         Tk_ErrorHandler handler;
647         XImage *bgImg = NULL;
648
649         /*
650          * Create an error handler to suppress the case where the input was
651          * not properly constrained, which can cause an X error. [Bug 979239]
652          */
653
654         handler = Tk_CreateErrorHandler(display, -1, -1, -1, NULL, NULL);
655
656         /*
657          * Pull the current background from the display to blend with
658          */
659
660         bgImg = XGetImage(display, drawable, drawableX, drawableY,
661                 (unsigned int)width, (unsigned int)height, AllPlanes, ZPixmap);
662         if (bgImg == NULL) {
663             Tk_DeleteErrorHandler(handler);
664             /* We failed to get the image, so draw without blending alpha.
665              * It's the best we can do.
666              */
667             goto fallBack;
668         }
669
670         BlendComplexAlpha(bgImg, instancePtr, imageX, imageY, width, height);
671
672         /*
673          * Color info is unimportant as we only do this operation for depth >=
674          * 15.
675          */
676
677         TkPutImage(NULL, 0, display, drawable, instancePtr->gc,
678                 bgImg, 0, 0, drawableX, drawableY,
679                 (unsigned int) width, (unsigned int) height);
680         XDestroyImage(bgImg);
681         Tk_DeleteErrorHandler(handler);
682     } else {
683         /*
684          * modelPtr->region describes which parts of the image contain valid
685          * data. We set this region as the clip mask for the gc, setting its
686          * origin appropriately, and use it when drawing the image.
687          */
688
689     fallBack:
690         TkSetRegion(display, instancePtr->gc,
691                 instancePtr->masterPtr->validRegion);
692         XSetClipOrigin(display, instancePtr->gc, drawableX - imageX,
693                 drawableY - imageY);
694         XCopyArea(display, instancePtr->pixels, drawable, instancePtr->gc,
695                 imageX, imageY, (unsigned) width, (unsigned) height,
696                 drawableX, drawableY);
697         XSetClipMask(display, instancePtr->gc, None);
698         XSetClipOrigin(display, instancePtr->gc, 0, 0);
699     }
700     (void)XFlush(display);
701 #endif
702 }
703 \f
704 /*
705  *----------------------------------------------------------------------
706  *
707  * TkImgPhotoFree --
708  *
709  *      This function is called when a widget ceases to use a particular
710  *      instance of an image. We don't actually get rid of the instance until
711  *      later because we may be about to get this instance again.
712  *
713  * Results:
714  *      None.
715  *
716  * Side effects:
717  *      Internal data structures get cleaned up, later.
718  *
719  *----------------------------------------------------------------------
720  */
721
722 void
723 TkImgPhotoFree(
724     ClientData clientData,      /* Pointer to PhotoInstance structure for
725                                  * instance to be displayed. */
726     Display *display)           /* Display containing window that used
727                                  * image. */
728 {
729     PhotoInstance *instancePtr = clientData;
730     ColorTable *colorPtr;
731
732     if (instancePtr->refCount-- > 1) {
733         return;
734     }
735
736     /*
737      * There are no more uses of the image within this widget. Decrement the
738      * count of live uses of its color table, so that its colors can be
739      * reclaimed if necessary, and set up an idle call to free the instance
740      * structure.
741      */
742
743     colorPtr = instancePtr->colorTablePtr;
744     if (colorPtr != NULL) {
745         colorPtr->liveRefCount -= 1;
746     }
747
748     Tcl_DoWhenIdle(TkImgDisposeInstance, instancePtr);
749 }
750 \f
751 /*
752  *----------------------------------------------------------------------
753  *
754  * TkImgPhotoInstanceSetSize --
755  *
756  *      This function reallocates the instance pixmap and dithering error
757  *      array for a photo instance, as necessary, to change the image's size
758  *      to `width' x `height' pixels.
759  *
760  * Results:
761  *      None.
762  *
763  * Side effects:
764  *      Storage gets reallocated, here and in the X server.
765  *
766  *----------------------------------------------------------------------
767  */
768
769 void
770 TkImgPhotoInstanceSetSize(
771     PhotoInstance *instancePtr) /* Instance whose size is to be changed. */
772 {
773     PhotoModel *modelPtr;
774     schar *newError, *errSrcPtr, *errDestPtr;
775     int h, offset;
776     XRectangle validBox;
777     Pixmap newPixmap;
778
779     modelPtr = instancePtr->masterPtr;
780     TkClipBox(modelPtr->validRegion, &validBox);
781
782     if ((instancePtr->width != modelPtr->width)
783             || (instancePtr->height != modelPtr->height)
784             || (instancePtr->pixels == None)) {
785         newPixmap = Tk_GetPixmap(instancePtr->display,
786                 RootWindow(instancePtr->display,
787                         instancePtr->visualInfo.screen),
788                 (modelPtr->width > 0) ? modelPtr->width: 1,
789                 (modelPtr->height > 0) ? modelPtr->height: 1,
790                 instancePtr->visualInfo.depth);
791         if (!newPixmap) {
792             Tcl_Panic("Fail to create pixmap with Tk_GetPixmap in TkImgPhotoInstanceSetSize");
793         }
794
795         /*
796          * The following is a gross hack needed to properly support colormaps
797          * under Windows. Before the pixels can be copied to the pixmap, the
798          * relevent colormap must be associated with the drawable. Normally we
799          * can infer this association from the window that was used to create
800          * the pixmap. However, in this case we're using the root window, so
801          * we have to be more explicit.
802          */
803
804         TkSetPixmapColormap(newPixmap, instancePtr->colormap);
805
806         if (instancePtr->pixels != None) {
807             /*
808              * Copy any common pixels from the old pixmap and free it.
809              */
810
811             XCopyArea(instancePtr->display, instancePtr->pixels, newPixmap,
812                     instancePtr->gc, validBox.x, validBox.y,
813                     validBox.width, validBox.height, validBox.x, validBox.y);
814             Tk_FreePixmap(instancePtr->display, instancePtr->pixels);
815         }
816         instancePtr->pixels = newPixmap;
817     }
818
819     if ((instancePtr->width != modelPtr->width)
820             || (instancePtr->height != modelPtr->height)
821             || (instancePtr->error == NULL)) {
822         if (modelPtr->height > 0 && modelPtr->width > 0) {
823             /*
824              * TODO: use attemptckalloc() here once there is a strategy that
825              * will allow us to recover from failure. Right now, there's no
826              * such possibility.
827              */
828
829             newError = ckalloc(modelPtr->height * modelPtr->width
830                     * 3 * sizeof(schar));
831
832             /*
833              * Zero the new array so that we don't get bogus error values
834              * propagating into areas we dither later.
835              */
836
837             if ((instancePtr->error != NULL)
838                     && ((instancePtr->width == modelPtr->width)
839                     || (validBox.width == modelPtr->width))) {
840                 if (validBox.y > 0) {
841                     memset(newError, 0, (size_t)
842                             validBox.y * modelPtr->width * 3 * sizeof(schar));
843                 }
844                 h = validBox.y + validBox.height;
845                 if (h < modelPtr->height) {
846                     memset(newError + h*modelPtr->width*3, 0,
847                             (size_t) (modelPtr->height - h)
848                             * modelPtr->width * 3 * sizeof(schar));
849                 }
850             } else {
851                 memset(newError, 0, (size_t)
852                         modelPtr->height * modelPtr->width *3*sizeof(schar));
853             }
854         } else {
855             newError = NULL;
856         }
857
858         if (instancePtr->error != NULL) {
859             /*
860              * Copy the common area over to the new array and free the old
861              * array.
862              */
863
864             if (modelPtr->width == instancePtr->width) {
865                 offset = validBox.y * modelPtr->width * 3;
866                 memcpy(newError + offset, instancePtr->error + offset,
867                         (size_t) (validBox.height
868                         * modelPtr->width * 3 * sizeof(schar)));
869
870             } else if (validBox.width > 0 && validBox.height > 0) {
871                 errDestPtr = newError +
872                         (validBox.y * modelPtr->width + validBox.x) * 3;
873                 errSrcPtr = instancePtr->error +
874                         (validBox.y * instancePtr->width + validBox.x) * 3;
875
876                 for (h = validBox.height; h > 0; --h) {
877                     memcpy(errDestPtr, errSrcPtr,
878                             validBox.width * 3 * sizeof(schar));
879                     errDestPtr += modelPtr->width * 3;
880                     errSrcPtr += instancePtr->width * 3;
881                 }
882             }
883             ckfree(instancePtr->error);
884         }
885
886         instancePtr->error = newError;
887     }
888
889     instancePtr->width = modelPtr->width;
890     instancePtr->height = modelPtr->height;
891 }
892 \f
893 /*
894  *----------------------------------------------------------------------
895  *
896  * IsValidPalette --
897  *
898  *      This function is called to check whether a value given for the
899  *      -palette option is valid for a particular instance of a photo image.
900  *
901  * Results:
902  *      A boolean value: 1 if the palette is acceptable, 0 otherwise.
903  *
904  * Side effects:
905  *      None.
906  *
907  *----------------------------------------------------------------------
908  */
909
910 static int
911 IsValidPalette(
912     PhotoInstance *instancePtr, /* Instance to which the palette specification
913                                  * is to be applied. */
914     const char *palette)        /* Palette specification string. */
915 {
916     int nRed, nGreen, nBlue, mono, numColors;
917     char *endp;
918
919     /*
920      * First parse the specification: it must be of the form %d or %d/%d/%d.
921      */
922
923     nRed = strtol(palette, &endp, 10);
924     if ((endp == palette) || ((*endp != 0) && (*endp != '/'))
925             || (nRed < 2) || (nRed > 256)) {
926         return 0;
927     }
928
929     if (*endp == 0) {
930         mono = 1;
931         nGreen = nBlue = nRed;
932     } else {
933         palette = endp + 1;
934         nGreen = strtol(palette, &endp, 10);
935         if ((endp == palette) || (*endp != '/') || (nGreen < 2)
936                 || (nGreen > 256)) {
937             return 0;
938         }
939         palette = endp + 1;
940         nBlue = strtol(palette, &endp, 10);
941         if ((endp == palette) || (*endp != 0) || (nBlue < 2)
942                 || (nBlue > 256)) {
943             return 0;
944         }
945         mono = 0;
946     }
947
948     switch (instancePtr->visualInfo.c_class) {
949     case DirectColor:
950     case TrueColor:
951         if ((nRed > (1 << CountBits(instancePtr->visualInfo.red_mask)))
952                 || (nGreen>(1<<CountBits(instancePtr->visualInfo.green_mask)))
953                 || (nBlue>(1<<CountBits(instancePtr->visualInfo.blue_mask)))) {
954             return 0;
955         }
956         break;
957     case PseudoColor:
958     case StaticColor:
959         numColors = nRed;
960         if (!mono) {
961             numColors *= nGreen * nBlue;
962         }
963         if (numColors > (1 << instancePtr->visualInfo.depth)) {
964             return 0;
965         }
966         break;
967     case GrayScale:
968     case StaticGray:
969         if (!mono || (nRed > (1 << instancePtr->visualInfo.depth))) {
970             return 0;
971         }
972         break;
973     }
974
975     return 1;
976 }
977 \f
978 /*
979  *----------------------------------------------------------------------
980  *
981  * CountBits --
982  *
983  *      This function counts how many bits are set to 1 in `mask'.
984  *
985  * Results:
986  *      The integer number of bits.
987  *
988  * Side effects:
989  *      None.
990  *
991  *----------------------------------------------------------------------
992  */
993
994 static int
995 CountBits(
996     pixel mask)                 /* Value to count the 1 bits in. */
997 {
998     int n;
999
1000     for (n=0 ; mask!=0 ; mask&=mask-1) {
1001         n++;
1002     }
1003     return n;
1004 }
1005 \f
1006 /*
1007  *----------------------------------------------------------------------
1008  *
1009  * GetColorTable --
1010  *
1011  *      This function is called to allocate a table of colormap information
1012  *      for an instance of a photo image. Only one such table is allocated for
1013  *      all photo instances using the same display, colormap, palette and
1014  *      gamma values, so that the application need only request a set of
1015  *      colors from the X server once for all such photo widgets. This
1016  *      function maintains a hash table to find previously-allocated
1017  *      ColorTables.
1018  *
1019  * Results:
1020  *      None.
1021  *
1022  * Side effects:
1023  *      A new ColorTable may be allocated and placed in the hash table, and
1024  *      have colors allocated for it.
1025  *
1026  *----------------------------------------------------------------------
1027  */
1028
1029 static void
1030 GetColorTable(
1031     PhotoInstance *instancePtr) /* Instance needing a color table. */
1032 {
1033     ColorTable *colorPtr;
1034     Tcl_HashEntry *entry;
1035     ColorTableId id;
1036     int isNew;
1037
1038     /*
1039      * Look for an existing ColorTable in the hash table.
1040      */
1041
1042     memset(&id, 0, sizeof(id));
1043     id.display = instancePtr->display;
1044     id.colormap = instancePtr->colormap;
1045     id.palette = instancePtr->palette;
1046     id.gamma = instancePtr->gamma;
1047     if (!imgPhotoColorHashInitialized) {
1048         Tcl_InitHashTable(&imgPhotoColorHash, N_COLOR_HASH);
1049         imgPhotoColorHashInitialized = 1;
1050     }
1051     entry = Tcl_CreateHashEntry(&imgPhotoColorHash, (char *) &id, &isNew);
1052
1053     if (!isNew) {
1054         /*
1055          * Re-use the existing entry.
1056          */
1057
1058         colorPtr = Tcl_GetHashValue(entry);
1059     } else {
1060         /*
1061          * No color table currently available; need to make one.
1062          */
1063
1064         colorPtr = ckalloc(sizeof(ColorTable));
1065
1066         /*
1067          * The following line of code should not normally be needed due to the
1068          * assignment in the following line. However, it compensates for bugs
1069          * in some compilers (HP, for example) where sizeof(ColorTable) is 24
1070          * but the assignment only copies 20 bytes, leaving 4 bytes
1071          * uninitialized; these cause problems when using the id for lookups
1072          * in imgPhotoColorHash, and can result in core dumps.
1073          */
1074
1075         memset(&colorPtr->id, 0, sizeof(ColorTableId));
1076         colorPtr->id = id;
1077         Tk_PreserveColormap(colorPtr->id.display, colorPtr->id.colormap);
1078         colorPtr->flags = 0;
1079         colorPtr->refCount = 0;
1080         colorPtr->liveRefCount = 0;
1081         colorPtr->numColors = 0;
1082         colorPtr->visualInfo = instancePtr->visualInfo;
1083         colorPtr->pixelMap = NULL;
1084         Tcl_SetHashValue(entry, colorPtr);
1085     }
1086
1087     colorPtr->refCount++;
1088     colorPtr->liveRefCount++;
1089     instancePtr->colorTablePtr = colorPtr;
1090     if (colorPtr->flags & DISPOSE_PENDING) {
1091         Tcl_CancelIdleCall(DisposeColorTable, colorPtr);
1092         colorPtr->flags &= ~DISPOSE_PENDING;
1093     }
1094
1095     /*
1096      * Allocate colors for this color table if necessary.
1097      */
1098
1099     if ((colorPtr->numColors == 0) && !(colorPtr->flags & BLACK_AND_WHITE)) {
1100         AllocateColors(colorPtr);
1101     }
1102 }
1103 \f
1104 /*
1105  *----------------------------------------------------------------------
1106  *
1107  * FreeColorTable --
1108  *
1109  *      This function is called when an instance ceases using a color table.
1110  *
1111  * Results:
1112  *      None.
1113  *
1114  * Side effects:
1115  *      If no other instances are using this color table, a when-idle handler
1116  *      is registered to free up the color table and the colors allocated for
1117  *      it.
1118  *
1119  *----------------------------------------------------------------------
1120  */
1121
1122 static void
1123 FreeColorTable(
1124     ColorTable *colorPtr,       /* Pointer to the color table which is no
1125                                  * longer required by an instance. */
1126     int force)                  /* Force free to happen immediately. */
1127 {
1128     colorPtr->refCount--;
1129     if (colorPtr->refCount > 0) {
1130         return;
1131     }
1132
1133     if (force) {
1134         if (colorPtr->flags & DISPOSE_PENDING) {
1135             Tcl_CancelIdleCall(DisposeColorTable, colorPtr);
1136             colorPtr->flags &= ~DISPOSE_PENDING;
1137         }
1138         DisposeColorTable(colorPtr);
1139     } else if (!(colorPtr->flags & DISPOSE_PENDING)) {
1140         Tcl_DoWhenIdle(DisposeColorTable, colorPtr);
1141         colorPtr->flags |= DISPOSE_PENDING;
1142     }
1143 }
1144 \f
1145 /*
1146  *----------------------------------------------------------------------
1147  *
1148  * AllocateColors --
1149  *
1150  *      This function allocates the colors required by a color table, and sets
1151  *      up the fields in the color table data structure which are used in
1152  *      dithering.
1153  *
1154  * Results:
1155  *      None.
1156  *
1157  * Side effects:
1158  *      Colors are allocated from the X server. Fields in the color table data
1159  *      structure are updated.
1160  *
1161  *----------------------------------------------------------------------
1162  */
1163
1164 static void
1165 AllocateColors(
1166     ColorTable *colorPtr)       /* Pointer to the color table requiring colors
1167                                  * to be allocated. */
1168 {
1169     int i, r, g, b, rMult, mono;
1170     int numColors, nRed, nGreen, nBlue;
1171     double fr, fg, fb, igam;
1172     XColor *colors;
1173     unsigned long *pixels;
1174
1175     /*
1176      * 16-bit intensity value for i/n of full intensity.
1177      */
1178 #define CFRAC(i, n)     ((i) * 65535 / (n))
1179
1180     /* As for CFRAC, but apply exponent of g. */
1181 #define CGFRAC(i, n, g) ((int)(65535 * pow((double)(i) / (n), (g))))
1182
1183     /*
1184      * First parse the palette specification to get the required number of
1185      * shades of each primary.
1186      */
1187
1188     mono = sscanf(colorPtr->id.palette, "%d/%d/%d", &nRed, &nGreen, &nBlue)
1189             <= 1;
1190     igam = 1.0 / colorPtr->id.gamma;
1191
1192     /*
1193      * Each time around this loop, we reduce the number of colors we're trying
1194      * to allocate until we succeed in allocating all of the colors we need.
1195      */
1196
1197     for (;;) {
1198         /*
1199          * If we are using 1 bit/pixel, we don't need to allocate any colors
1200          * (we just use the foreground and background colors in the GC).
1201          */
1202
1203         if (mono && (nRed <= 2)) {
1204             colorPtr->flags |= BLACK_AND_WHITE;
1205             return;
1206         }
1207
1208         /*
1209          * Calculate the RGB coordinates of the colors we want to allocate and
1210          * store them in *colors.
1211          */
1212
1213         if ((colorPtr->visualInfo.c_class == DirectColor)
1214                 || (colorPtr->visualInfo.c_class == TrueColor)) {
1215
1216             /*
1217              * Direct/True Color: allocate shades of red, green, blue
1218              * independently.
1219              */
1220
1221             if (mono) {
1222                 numColors = nGreen = nBlue = nRed;
1223             } else {
1224                 numColors = MAX(MAX(nRed, nGreen), nBlue);
1225             }
1226             colors = ckalloc(numColors * sizeof(XColor));
1227
1228             for (i = 0; i < numColors; ++i) {
1229                 if (igam == 1.0) {
1230                     colors[i].red = CFRAC(i, nRed - 1);
1231                     colors[i].green = CFRAC(i, nGreen - 1);
1232                     colors[i].blue = CFRAC(i, nBlue - 1);
1233                 } else {
1234                     colors[i].red = CGFRAC(i, nRed - 1, igam);
1235                     colors[i].green = CGFRAC(i, nGreen - 1, igam);
1236                     colors[i].blue = CGFRAC(i, nBlue - 1, igam);
1237                 }
1238             }
1239         } else {
1240             /*
1241              * PseudoColor, StaticColor, GrayScale or StaticGray visual: we
1242              * have to allocate each color in the color cube separately.
1243              */
1244
1245             numColors = (mono) ? nRed: (nRed * nGreen * nBlue);
1246             colors = ckalloc(numColors * sizeof(XColor));
1247
1248             if (!mono) {
1249                 /*
1250                  * Color display using a PseudoColor or StaticColor visual.
1251                  */
1252
1253                 i = 0;
1254                 for (r = 0; r < nRed; ++r) {
1255                     for (g = 0; g < nGreen; ++g) {
1256                         for (b = 0; b < nBlue; ++b) {
1257                             if (igam == 1.0) {
1258                                 colors[i].red = CFRAC(r, nRed - 1);
1259                                 colors[i].green = CFRAC(g, nGreen - 1);
1260                                 colors[i].blue = CFRAC(b, nBlue - 1);
1261                             } else {
1262                                 colors[i].red = CGFRAC(r, nRed - 1, igam);
1263                                 colors[i].green = CGFRAC(g, nGreen - 1, igam);
1264                                 colors[i].blue = CGFRAC(b, nBlue - 1, igam);
1265                             }
1266                             i++;
1267                         }
1268                     }
1269                 }
1270             } else {
1271                 /*
1272                  * Monochrome display - allocate the shades of gray we want.
1273                  */
1274
1275                 for (i = 0; i < numColors; ++i) {
1276                     if (igam == 1.0) {
1277                         r = CFRAC(i, numColors - 1);
1278                     } else {
1279                         r = CGFRAC(i, numColors - 1, igam);
1280                     }
1281                     colors[i].red = colors[i].green = colors[i].blue = r;
1282                 }
1283             }
1284         }
1285
1286         /*
1287          * Now try to allocate the colors we've calculated.
1288          */
1289
1290         pixels = ckalloc(numColors * sizeof(unsigned long));
1291         for (i = 0; i < numColors; ++i) {
1292             if (!XAllocColor(colorPtr->id.display, colorPtr->id.colormap,
1293                     &colors[i])) {
1294                 /*
1295                  * Can't get all the colors we want in the default colormap;
1296                  * first try freeing colors from other unused color tables.
1297                  */
1298
1299                 if (!ReclaimColors(&colorPtr->id, numColors - i)
1300                         || !XAllocColor(colorPtr->id.display,
1301                         colorPtr->id.colormap, &colors[i])) {
1302                     /*
1303                      * Still can't allocate the color.
1304                      */
1305
1306                     break;
1307                 }
1308             }
1309             pixels[i] = colors[i].pixel;
1310         }
1311
1312         /*
1313          * If we didn't get all of the colors, reduce the resolution of the
1314          * color cube, free the ones we got, and try again.
1315          */
1316
1317         if (i >= numColors) {
1318             break;
1319         }
1320         XFreeColors(colorPtr->id.display, colorPtr->id.colormap, pixels, i, 0);
1321         ckfree(colors);
1322         ckfree(pixels);
1323
1324         if (!mono) {
1325             if ((nRed == 2) && (nGreen == 2) && (nBlue == 2)) {
1326                 /*
1327                  * Fall back to 1-bit monochrome display.
1328                  */
1329
1330                 mono = 1;
1331             } else {
1332                 /*
1333                  * Reduce the number of shades of each primary to about 3/4 of
1334                  * the previous value. This should reduce the total number of
1335                  * colors required to about half the previous value for
1336                  * PseudoColor displays.
1337                  */
1338
1339                 nRed = (nRed * 3 + 2) / 4;
1340                 nGreen = (nGreen * 3 + 2) / 4;
1341                 nBlue = (nBlue * 3 + 2) / 4;
1342             }
1343         } else {
1344             /*
1345              * Reduce the number of shades of gray to about 1/2.
1346              */
1347
1348             nRed = nRed / 2;
1349         }
1350     }
1351
1352     /*
1353      * We have allocated all of the necessary colors: fill in various fields
1354      * of the ColorTable record.
1355      */
1356
1357     if (!mono) {
1358         colorPtr->flags |= COLOR_WINDOW;
1359
1360         /*
1361          * The following is a hairy hack. We only want to index into the
1362          * pixelMap on colormap displays. However, if the display is on
1363          * Windows, then we actually want to store the index not the value
1364          * since we will be passing the color table into the TkPutImage call.
1365          */
1366
1367 #ifndef _WIN32
1368         if ((colorPtr->visualInfo.c_class != DirectColor)
1369                 && (colorPtr->visualInfo.c_class != TrueColor)) {
1370             colorPtr->flags |= MAP_COLORS;
1371         }
1372 #endif /* _WIN32 */
1373     }
1374
1375     colorPtr->numColors = numColors;
1376     colorPtr->pixelMap = pixels;
1377
1378     /*
1379      * Set up quantization tables for dithering.
1380      */
1381
1382     rMult = nGreen * nBlue;
1383     for (i = 0; i < 256; ++i) {
1384         r = (i * (nRed - 1) + 127) / 255;
1385         if (mono) {
1386             fr = (double) colors[r].red / 65535.0;
1387             if (colorPtr->id.gamma != 1.0 ) {
1388                 fr = pow(fr, colorPtr->id.gamma);
1389             }
1390             colorPtr->colorQuant[0][i] = (int)(fr * 255.99);
1391             colorPtr->redValues[i] = colors[r].pixel;
1392         } else {
1393             g = (i * (nGreen - 1) + 127) / 255;
1394             b = (i * (nBlue - 1) + 127) / 255;
1395             if ((colorPtr->visualInfo.c_class == DirectColor)
1396                     || (colorPtr->visualInfo.c_class == TrueColor)) {
1397                 colorPtr->redValues[i] =
1398                         colors[r].pixel & colorPtr->visualInfo.red_mask;
1399                 colorPtr->greenValues[i] =
1400                         colors[g].pixel & colorPtr->visualInfo.green_mask;
1401                 colorPtr->blueValues[i] =
1402                         colors[b].pixel & colorPtr->visualInfo.blue_mask;
1403             } else {
1404                 r *= rMult;
1405                 g *= nBlue;
1406                 colorPtr->redValues[i] = r;
1407                 colorPtr->greenValues[i] = g;
1408                 colorPtr->blueValues[i] = b;
1409             }
1410             fr = (double) colors[r].red / 65535.0;
1411             fg = (double) colors[g].green / 65535.0;
1412             fb = (double) colors[b].blue / 65535.0;
1413             if (colorPtr->id.gamma != 1.0) {
1414                 fr = pow(fr, colorPtr->id.gamma);
1415                 fg = pow(fg, colorPtr->id.gamma);
1416                 fb = pow(fb, colorPtr->id.gamma);
1417             }
1418             colorPtr->colorQuant[0][i] = (int)(fr * 255.99);
1419             colorPtr->colorQuant[1][i] = (int)(fg * 255.99);
1420             colorPtr->colorQuant[2][i] = (int)(fb * 255.99);
1421         }
1422     }
1423
1424     ckfree(colors);
1425 }
1426 \f
1427 /*
1428  *----------------------------------------------------------------------
1429  *
1430  * DisposeColorTable --
1431  *
1432  *      Release a color table and its associated resources.
1433  *
1434  * Results:
1435  *      None.
1436  *
1437  * Side effects:
1438  *      The colors in the argument color table are freed, as is the color
1439  *      table structure itself. The color table is removed from the hash table
1440  *      which is used to locate color tables.
1441  *
1442  *----------------------------------------------------------------------
1443  */
1444
1445 static void
1446 DisposeColorTable(
1447     ClientData clientData)      /* Pointer to the ColorTable whose
1448                                  * colors are to be released. */
1449 {
1450     ColorTable *colorPtr = clientData;
1451     Tcl_HashEntry *entry;
1452
1453     if (colorPtr->pixelMap != NULL) {
1454         if (colorPtr->numColors > 0) {
1455             XFreeColors(colorPtr->id.display, colorPtr->id.colormap,
1456                     colorPtr->pixelMap, colorPtr->numColors, 0);
1457             Tk_FreeColormap(colorPtr->id.display, colorPtr->id.colormap);
1458         }
1459         ckfree(colorPtr->pixelMap);
1460     }
1461
1462     entry = Tcl_FindHashEntry(&imgPhotoColorHash, (char *) &colorPtr->id);
1463     if (entry == NULL) {
1464         Tcl_Panic("DisposeColorTable couldn't find hash entry");
1465     }
1466     Tcl_DeleteHashEntry(entry);
1467
1468     ckfree(colorPtr);
1469 }
1470 \f
1471 /*
1472  *----------------------------------------------------------------------
1473  *
1474  * ReclaimColors --
1475  *
1476  *      This function is called to try to free up colors in the colormap used
1477  *      by a color table. It looks for other color tables with the same
1478  *      colormap and with a zero live reference count, and frees their colors.
1479  *      It only does so if there is the possibility of freeing up at least
1480  *      `numColors' colors.
1481  *
1482  * Results:
1483  *      The return value is TRUE if any colors were freed, FALSE otherwise.
1484  *
1485  * Side effects:
1486  *      ColorTables which are not currently in use may lose their color
1487  *      allocations.
1488  *
1489  *----------------------------------------------------------------------
1490  */
1491
1492 static int
1493 ReclaimColors(
1494     ColorTableId *id,           /* Pointer to information identifying
1495                                  * the color table which needs more colors. */
1496     int numColors)              /* Number of colors required. */
1497 {
1498     Tcl_HashSearch srch;
1499     Tcl_HashEntry *entry;
1500     ColorTable *colorPtr;
1501     int nAvail = 0;
1502
1503     /*
1504      * First scan through the color hash table to get an upper bound on how
1505      * many colors we might be able to free.
1506      */
1507
1508     entry = Tcl_FirstHashEntry(&imgPhotoColorHash, &srch);
1509     while (entry != NULL) {
1510         colorPtr = Tcl_GetHashValue(entry);
1511         if ((colorPtr->id.display == id->display)
1512                 && (colorPtr->id.colormap == id->colormap)
1513                 && (colorPtr->liveRefCount == 0 )&& (colorPtr->numColors != 0)
1514                 && ((colorPtr->id.palette != id->palette)
1515                         || (colorPtr->id.gamma != id->gamma))) {
1516             /*
1517              * We could take this guy's colors off him.
1518              */
1519
1520             nAvail += colorPtr->numColors;
1521         }
1522         entry = Tcl_NextHashEntry(&srch);
1523     }
1524
1525     /*
1526      * nAvail is an (over)estimate of the number of colors we could free.
1527      */
1528
1529     if (nAvail < numColors) {
1530         return 0;
1531     }
1532
1533     /*
1534      * Scan through a second time freeing colors.
1535      */
1536
1537     entry = Tcl_FirstHashEntry(&imgPhotoColorHash, &srch);
1538     while ((entry != NULL) && (numColors > 0)) {
1539         colorPtr = Tcl_GetHashValue(entry);
1540         if ((colorPtr->id.display == id->display)
1541                 && (colorPtr->id.colormap == id->colormap)
1542                 && (colorPtr->liveRefCount == 0) && (colorPtr->numColors != 0)
1543                 && ((colorPtr->id.palette != id->palette)
1544                         || (colorPtr->id.gamma != id->gamma))) {
1545             /*
1546              * Free the colors that this ColorTable has.
1547              */
1548
1549             XFreeColors(colorPtr->id.display, colorPtr->id.colormap,
1550                     colorPtr->pixelMap, colorPtr->numColors, 0);
1551             numColors -= colorPtr->numColors;
1552             colorPtr->numColors = 0;
1553             ckfree(colorPtr->pixelMap);
1554             colorPtr->pixelMap = NULL;
1555         }
1556
1557         entry = Tcl_NextHashEntry(&srch);
1558     }
1559     return 1;                   /* We freed some colors. */
1560 }
1561 \f
1562 /*
1563  *----------------------------------------------------------------------
1564  *
1565  * TkImgDisposeInstance --
1566  *
1567  *      This function is called to finally free up an instance of a photo
1568  *      image which is no longer required.
1569  *
1570  * Results:
1571  *      None.
1572  *
1573  * Side effects:
1574  *      The instance data structure and the resources it references are freed.
1575  *
1576  *----------------------------------------------------------------------
1577  */
1578
1579 void
1580 TkImgDisposeInstance(
1581     ClientData clientData)      /* Pointer to the instance whose resources are
1582                                  * to be released. */
1583 {
1584     PhotoInstance *instancePtr = clientData;
1585     PhotoInstance *prevPtr;
1586
1587     if (instancePtr->pixels != None) {
1588         Tk_FreePixmap(instancePtr->display, instancePtr->pixels);
1589     }
1590     if (instancePtr->gc != NULL) {
1591         Tk_FreeGC(instancePtr->display, instancePtr->gc);
1592     }
1593     if (instancePtr->imagePtr != NULL) {
1594         XDestroyImage(instancePtr->imagePtr);
1595     }
1596     if (instancePtr->error != NULL) {
1597         ckfree(instancePtr->error);
1598     }
1599     if (instancePtr->colorTablePtr != NULL) {
1600         FreeColorTable(instancePtr->colorTablePtr, 1);
1601     }
1602
1603     if (instancePtr->masterPtr->instancePtr == instancePtr) {
1604         instancePtr->masterPtr->instancePtr = instancePtr->nextPtr;
1605     } else {
1606         for (prevPtr = instancePtr->masterPtr->instancePtr;
1607                 prevPtr->nextPtr != instancePtr; prevPtr = prevPtr->nextPtr) {
1608             /* Empty loop body. */
1609         }
1610         prevPtr->nextPtr = instancePtr->nextPtr;
1611     }
1612     Tk_FreeColormap(instancePtr->display, instancePtr->colormap);
1613     ckfree(instancePtr);
1614 }
1615 \f
1616 /*
1617  *----------------------------------------------------------------------
1618  *
1619  * TkImgDitherInstance --
1620  *
1621  *      This function is called to update an area of an instance's pixmap by
1622  *      dithering the corresponding area of the model.
1623  *
1624  * Results:
1625  *      None.
1626  *
1627  * Side effects:
1628  *      The instance's pixmap gets updated.
1629  *
1630  *----------------------------------------------------------------------
1631  */
1632
1633 void
1634 TkImgDitherInstance(
1635     PhotoInstance *instancePtr, /* The instance to be updated. */
1636     int xStart, int yStart,     /* Coordinates of the top-left pixel in the
1637                                  * block to be dithered. */
1638     int width, int height)      /* Dimensions of the block to be dithered. */
1639 {
1640     PhotoModel *modelPtr = instancePtr->masterPtr;
1641     ColorTable *colorPtr = instancePtr->colorTablePtr;
1642     XImage *imagePtr;
1643     int nLines, bigEndian, i, c, x, y, xEnd, doDithering = 1;
1644     int bitsPerPixel, bytesPerLine, lineLength;
1645     unsigned char *srcLinePtr;
1646     schar *errLinePtr;
1647     pixel firstBit, word, mask;
1648
1649     /*
1650      * Turn dithering off in certain cases where it is not needed (TrueColor,
1651      * DirectColor with many colors).
1652      */
1653
1654     if ((colorPtr->visualInfo.c_class == DirectColor)
1655             || (colorPtr->visualInfo.c_class == TrueColor)) {
1656         int nRed, nGreen, nBlue, result;
1657
1658         result = sscanf(colorPtr->id.palette, "%d/%d/%d", &nRed,
1659                 &nGreen, &nBlue);
1660         if ((nRed >= 256)
1661                 && ((result == 1) || ((nGreen >= 256) && (nBlue >= 256)))) {
1662             doDithering = 0;
1663         }
1664     }
1665
1666     /*
1667      * First work out how many lines to do at a time, then how many bytes
1668      * we'll need for pixel storage, and allocate it.
1669      */
1670
1671     nLines = (MAX_PIXELS + width - 1) / width;
1672     if (nLines < 1) {
1673         nLines = 1;
1674     }
1675     if (nLines > height ) {
1676         nLines = height;
1677     }
1678
1679     imagePtr = instancePtr->imagePtr;
1680     if (imagePtr == NULL) {
1681         return;                 /* We must be really tight on memory. */
1682     }
1683     bitsPerPixel = imagePtr->bits_per_pixel;
1684     bytesPerLine = ((bitsPerPixel * width + 31) >> 3) & ~3;
1685     imagePtr->width = width;
1686     imagePtr->height = nLines;
1687     imagePtr->bytes_per_line = bytesPerLine;
1688
1689     /*
1690      * TODO: use attemptckalloc() here once we have some strategy for
1691      * recovering from the failure.
1692      */
1693
1694     imagePtr->data = ckalloc(imagePtr->bytes_per_line * nLines);
1695     bigEndian = imagePtr->bitmap_bit_order == MSBFirst;
1696     firstBit = bigEndian? (1 << (imagePtr->bitmap_unit - 1)): 1;
1697
1698     lineLength = modelPtr->width * 3;
1699     srcLinePtr = modelPtr->pix32 + (yStart * modelPtr->width + xStart) * 4;
1700     errLinePtr = instancePtr->error + yStart * lineLength + xStart * 3;
1701     xEnd = xStart + width;
1702
1703     /*
1704      * Loop over the image, doing at most nLines lines before updating the
1705      * screen image.
1706      */
1707
1708     for (; height > 0; height -= nLines) {
1709         unsigned char *dstLinePtr = (unsigned char *) imagePtr->data;
1710         int yEnd;
1711
1712         if (nLines > height) {
1713             nLines = height;
1714         }
1715         yEnd = yStart + nLines;
1716         for (y = yStart; y < yEnd; ++y) {
1717             unsigned char *srcPtr = srcLinePtr;
1718             schar *errPtr = errLinePtr;
1719             unsigned char *destBytePtr = dstLinePtr;
1720             pixel *destLongPtr = (pixel *) dstLinePtr;
1721
1722             if (colorPtr->flags & COLOR_WINDOW) {
1723                 /*
1724                  * Color window. We dither the three components independently,
1725                  * using Floyd-Steinberg dithering, which propagates errors
1726                  * from the quantization of pixels to the pixels below and to
1727                  * the right.
1728                  */
1729
1730                 for (x = xStart; x < xEnd; ++x) {
1731                     int col[3];
1732
1733                     if (doDithering) {
1734                         for (i = 0; i < 3; ++i) {
1735                             /*
1736                              * Compute the error propagated into this pixel
1737                              * for this component. If e[x,y] is the array of
1738                              * quantization error values, we compute
1739                              *     7/16 * e[x-1,y] + 1/16 * e[x-1,y-1]
1740                              *   + 5/16 * e[x,y-1] + 3/16 * e[x+1,y-1]
1741                              * and round it to an integer.
1742                              *
1743                              * The expression ((c + 2056) >> 4) - 128 computes
1744                              * round(c / 16), and works correctly on machines
1745                              * without a sign-extending right shift.
1746                              */
1747
1748                             c = (x > 0) ? errPtr[-3] * 7: 0;
1749                             if (y > 0) {
1750                                 if (x > 0) {
1751                                     c += errPtr[-lineLength-3];
1752                                 }
1753                                 c += errPtr[-lineLength] * 5;
1754                                 if ((x + 1) < modelPtr->width) {
1755                                     c += errPtr[-lineLength+3] * 3;
1756                                 }
1757                             }
1758
1759                             /*
1760                              * Add the propagated error to the value of this
1761                              * component, quantize it, and store the
1762                              * quantization error.
1763                              */
1764
1765                             c = ((c + 2056) >> 4) - 128 + *srcPtr++;
1766                             if (c < 0) {
1767                                 c = 0;
1768                             } else if (c > 255) {
1769                                 c = 255;
1770                             }
1771                             col[i] = colorPtr->colorQuant[i][c];
1772                             *errPtr++ = c - col[i];
1773                         }
1774                     } else {
1775                         /*
1776                          * Output is virtually continuous in this case, so
1777                          * don't bother dithering.
1778                          */
1779
1780                         col[0] = *srcPtr++;
1781                         col[1] = *srcPtr++;
1782                         col[2] = *srcPtr++;
1783                     }
1784                     srcPtr++;
1785
1786                     /*
1787                      * Translate the quantized component values into an X
1788                      * pixel value, and store it in the image.
1789                      */
1790
1791                     i = colorPtr->redValues[col[0]]
1792                             + colorPtr->greenValues[col[1]]
1793                             + colorPtr->blueValues[col[2]];
1794                     if (colorPtr->flags & MAP_COLORS) {
1795                         i = colorPtr->pixelMap[i];
1796                     }
1797                     switch (bitsPerPixel) {
1798                     case NBBY:
1799                         *destBytePtr++ = i;
1800                         break;
1801 #ifndef _WIN32
1802                         /*
1803                          * This case is not valid for Windows because the
1804                          * image format is different from the pixel format in
1805                          * Win32. Eventually we need to fix the image code in
1806                          * Tk to use the Windows native image ordering. This
1807                          * would speed up the image code for all of the common
1808                          * sizes.
1809                          */
1810
1811                     case NBBY * sizeof(pixel):
1812                         *destLongPtr++ = i;
1813                         break;
1814 #endif
1815                     default:
1816                         XPutPixel(imagePtr, x - xStart, y - yStart,
1817                                 (unsigned) i);
1818                     }
1819                 }
1820
1821             } else if (bitsPerPixel > 1) {
1822                 /*
1823                  * Multibit monochrome window. The operation here is similar
1824                  * to the color window case above, except that there is only
1825                  * one component. If the model image is in color, use the
1826                  * luminance computed as
1827                  *      0.344 * red + 0.5 * green + 0.156 * blue.
1828                  */
1829
1830                 for (x = xStart; x < xEnd; ++x) {
1831                     c = (x > 0) ? errPtr[-1] * 7: 0;
1832                     if (y > 0) {
1833                         if (x > 0) {
1834                             c += errPtr[-lineLength-1];
1835                         }
1836                         c += errPtr[-lineLength] * 5;
1837                         if (x + 1 < modelPtr->width) {
1838                             c += errPtr[-lineLength+1] * 3;
1839                         }
1840                     }
1841                     c = ((c + 2056) >> 4) - 128;
1842
1843                     if (modelPtr->flags & COLOR_IMAGE) {
1844                         c += (unsigned) (srcPtr[0] * 11 + srcPtr[1] * 16
1845                                 + srcPtr[2] * 5 + 16) >> 5;
1846                     } else {
1847                         c += srcPtr[0];
1848                     }
1849                     srcPtr += 4;
1850
1851                     if (c < 0) {
1852                         c = 0;
1853                     } else if (c > 255) {
1854                         c = 255;
1855                     }
1856                     i = colorPtr->colorQuant[0][c];
1857                     *errPtr++ = c - i;
1858                     i = colorPtr->redValues[i];
1859                     switch (bitsPerPixel) {
1860                     case NBBY:
1861                         *destBytePtr++ = i;
1862                         break;
1863 #ifndef _WIN32
1864                         /*
1865                          * This case is not valid for Windows because the
1866                          * image format is different from the pixel format in
1867                          * Win32. Eventually we need to fix the image code in
1868                          * Tk to use the Windows native image ordering. This
1869                          * would speed up the image code for all of the common
1870                          * sizes.
1871                          */
1872
1873                     case NBBY * sizeof(pixel):
1874                         *destLongPtr++ = i;
1875                         break;
1876 #endif
1877                     default:
1878                         XPutPixel(imagePtr, x - xStart, y - yStart,
1879                                 (unsigned) i);
1880                     }
1881                 }
1882             } else {
1883                 /*
1884                  * 1-bit monochrome window. This is similar to the multibit
1885                  * monochrome case above, except that the quantization is
1886                  * simpler (we only have black = 0 and white = 255), and we
1887                  * produce an XY-Bitmap.
1888                  */
1889
1890                 word = 0;
1891                 mask = firstBit;
1892                 for (x = xStart; x < xEnd; ++x) {
1893                     /*
1894                      * If we have accumulated a whole word, store it in the
1895                      * image and start a new word.
1896                      */
1897
1898                     if (mask == 0) {
1899                         *destLongPtr++ = word;
1900                         mask = firstBit;
1901                         word = 0;
1902                     }
1903
1904                     c = (x > 0) ? errPtr[-1] * 7: 0;
1905                     if (y > 0) {
1906                         if (x > 0) {
1907                             c += errPtr[-lineLength-1];
1908                         }
1909                         c += errPtr[-lineLength] * 5;
1910                         if (x + 1 < modelPtr->width) {
1911                             c += errPtr[-lineLength+1] * 3;
1912                         }
1913                     }
1914                     c = ((c + 2056) >> 4) - 128;
1915
1916                     if (modelPtr->flags & COLOR_IMAGE) {
1917                         c += (unsigned)(srcPtr[0] * 11 + srcPtr[1] * 16
1918                                 + srcPtr[2] * 5 + 16) >> 5;
1919                     } else {
1920                         c += srcPtr[0];
1921                     }
1922                     srcPtr += 4;
1923
1924                     if (c < 0) {
1925                         c = 0;
1926                     } else if (c > 255) {
1927                         c = 255;
1928                     }
1929                     if (c >= 128) {
1930                         word |= mask;
1931                         *errPtr++ = c - 255;
1932                     } else {
1933                         *errPtr++ = c;
1934                     }
1935                     mask = bigEndian? (mask >> 1): (mask << 1);
1936                 }
1937                 *destLongPtr = word;
1938             }
1939             srcLinePtr += modelPtr->width * 4;
1940             errLinePtr += lineLength;
1941             dstLinePtr += bytesPerLine;
1942         }
1943
1944         /*
1945          * Update the pixmap for this instance with the block of pixels that
1946          * we have just computed.
1947          */
1948
1949         TkPutImage(colorPtr->pixelMap, colorPtr->numColors,
1950                 instancePtr->display, instancePtr->pixels,
1951                 instancePtr->gc, imagePtr, 0, 0, xStart, yStart,
1952                 (unsigned) width, (unsigned) nLines);
1953         yStart = yEnd;
1954     }
1955
1956     ckfree(imagePtr->data);
1957     imagePtr->data = NULL;
1958 }
1959 \f
1960 /*
1961  *----------------------------------------------------------------------
1962  *
1963  * TkImgResetDither --
1964  *
1965  *      This function is called to eliminate the content of a photo instance's
1966  *      dither error buffer. It's called when the overall image is blanked.
1967  *
1968  * Results:
1969  *      None.
1970  *
1971  * Side effects:
1972  *      The instance's dither buffer gets cleared.
1973  *
1974  *----------------------------------------------------------------------
1975  */
1976
1977 void
1978 TkImgResetDither(
1979     PhotoInstance *instancePtr)
1980 {
1981     if (instancePtr->error) {
1982         memset(instancePtr->error, 0,
1983                /*(size_t)*/ (instancePtr->masterPtr->width
1984                 * instancePtr->masterPtr->height * 3 * sizeof(schar)));
1985     }
1986 }
1987 \f
1988 /*
1989  * Local Variables:
1990  * mode: c
1991  * c-basic-offset: 4
1992  * fill-column: 78
1993  * End:
1994  */