Add GNU LGPL headers to all .c .C and .h files
[oweals/cde.git] / cde / lib / DtHelp / il / ilreadX.c
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these librararies and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 /* $XConsortium: ilreadX.c /main/3 1995/10/23 15:59:17 rswiston $ */
24 /**---------------------------------------------------------------------
25 ***     
26 ***    (c)Copyright 1991 Hewlett-Packard Co.
27 ***    
28 ***                             RESTRICTED RIGHTS LEGEND
29 ***    Use, duplication, or disclosure by the U.S. Government is subject to
30 ***    restrictions as set forth in sub-paragraph (c)(1)(ii) of the Rights in
31 ***    Technical Data and Computer Software clause in DFARS 252.227-7013.
32 ***                             Hewlett-Packard Company
33 ***                             3000 Hanover Street
34 ***                             Palo Alto, CA 94304 U.S.A.
35 ***    Rights for non-DOD U.S. Government Departments and Agencies are as set
36 ***    forth in FAR 52.227-19(c)(1,2).
37 ***
38 ***-------------------------------------------------------------------*/
39
40
41 #include "ilint.h"
42 #include "ilcontext.h"
43 #include "ilX.h"
44 #include <math.h>
45 #include <X11/Xutil.h>
46 #include "ilpipelem.h"
47 #include "ilerrors.h"
48
49         /*  Bit-flip table, in /ilc/ildata.c */
50 extern const unsigned char ilBitReverseTable [];
51
52         /*  Private data for all ilReadXDrawable() pipe functions. */
53 typedef struct {
54     Display            *display;            /* copy of X display ptr */
55     Drawable            drawable;           /* given to / derived by ilReadXDrawable() */
56     Visual             *visual;             /* ptr to visual or null if a bitmap */
57     Colormap            colormap;           /* ptr to colormap or null if a bitmap */
58     int                 colormapSize;       /* # of entries in the colormap */
59     unsigned short     *pPalette;           /* palette for Pseudo/StaticColor or null */
60     ilClientImage       grayMapImage;       /* ilMap() image for gray or null */
61     ilPtr               pGrayMapPixels;     /* ptr to pixels in grayMapImage if non-null */
62     ilBool              isLongImage;        /* long/pixel format (24 bit drawable) */
63     ilClientImage       rgbMapImage;        /* ilMap() image for rgb or null */
64     ilPtr               pRGBMapPixels;      /* ptr to pixels in rgbMapImage if non-null */
65     ilRect              rect;               /* piece of X image to read */
66     long                stripHeight;        /* height of each piece of drawable to read */
67     int                 copyPixmapDepth;    /* depth for copyPixmap, or 0 => dont create */
68     Pixmap              copyPixmap;         /* pixmap to copy to/GetImage() from or null */
69     GC                  copyGC;             /* GC to use to copy to "copyPixmap" */
70     int                 nRedOnes;
71     int                 nGreenOnes;
72     int                 nBlueOnes;
73     int                 nRedZeros;
74     int                 nGreenZeros;
75     int                 nBlueZeros;
76     Bool                SlowMode;
77     int                 OrgRedMask;
78     int                 OrgGreenMask;
79     int                 OrgBlueMask; 
80     } ilReadXPrivRec, *ilReadXPrivPtr;
81
82
83         /*  ------------------------ ilReadXInit ------------------------------- */
84         /*  Init() function for ilReadXDrawable() pipe elements.
85         */
86 static ilError ilReadXInit (
87     ilReadXPrivPtr      pPriv,
88     ilImageInfo        *pSrcImage,
89     ilImageInfo        *pDstImage
90     )
91 {
92 #define                 NCOLORS 256
93 #define                 NGRAYS  256
94 #define                 NRGBS   256
95 ilReadXPrivRec              priv;  
96         /*  Init the palette if present by querying the colormap, with # entries =
97             pPriv->colormapSize (limit to NCOLORS; may be less, so init unused to black).
98         */
99     if (pPriv->pPalette) {
100         int             i;
101         XColor          cells [NCOLORS], *pColor;
102         unsigned short *pPalette;
103
104         for (i = 0, pColor = cells; i < NCOLORS; i++, pColor++) {
105             pColor->red = pColor->green = pColor->blue = 0;
106             pColor->pixel = i;
107             }
108         XQueryColors (pPriv->display, pPriv->colormap, cells, 
109                       (pPriv->colormapSize > NCOLORS) ? NCOLORS : pPriv->colormapSize);
110         for (i = 0, pPalette = pPriv->pPalette, pColor = cells; i < NCOLORS;
111          i++, pPalette++, pColor++) {
112             pPalette[0*256] = pColor->red;
113             pPalette[1*256] = pColor->green;
114             pPalette[2*256] = pColor->blue;
115             }
116         }
117
118         /*  If a grayMapImage, reading from grayscale: query the colormap and store
119             the upper 8 bits of the green value into grayMapImage, which is used
120             by an ilMap() filter which follows the ilReadXDrawable() (added there).
121         */
122     else if (pPriv->grayMapImage) {
123         int             i;
124         XColor          cells [NGRAYS], *pColor;
125         ilPtr           pByte;
126
127         for (i = 0, pColor = cells; i < NGRAYS; i++, pColor++) {
128             pColor->red = pColor->green = pColor->blue = 0;
129             pColor->pixel = i;
130             }
131         XQueryColors (pPriv->display, pPriv->colormap, cells, 
132                       (pPriv->colormapSize > NGRAYS) ? NGRAYS : pPriv->colormapSize);
133         for (i = 0, pByte = pPriv->pGrayMapPixels, pColor = cells; i < NGRAYS;
134          i++, pColor++)
135             *pByte++ = pColor->green >> 8;
136         }
137
138         /*  If an rgbMapImage, reading from True/DirectColor: query color - RGBs are
139             independent.  Init the mapImage which is 3 byte (rgb) per pixel.
140         */
141     else if (pPriv->rgbMapImage) {
142         int             i;
143         XColor          cells [NRGBS], *pColor;
144         ilPtr           pByte;
145
146         for (i = 0, pColor = cells; i < NRGBS; i++, pColor++) {
147             
148           if(!(pPriv->SlowMode)){
149             pColor->red = pColor->green = pColor->blue = 0;
150             pColor->pixel = ((i << 16) | (i << 8) | i);
151                   }
152           else {
153              
154             pColor->red = pColor->green = pColor->blue = 0;
155             pColor->pixel = ((i << pPriv->nRedZeros) | (i << pPriv->nGreenZeros) | 
156                               i << pPriv->nBlueZeros);
157                   }
158             }
159         XQueryColors (pPriv->display, pPriv->colormap, cells, 
160                       (pPriv->colormapSize > NRGBS) ? NRGBS : pPriv->colormapSize);
161         for (i = 0, pByte = pPriv->pRGBMapPixels, pColor = cells; i < NRGBS;
162          i++, pColor++) {
163             *pByte++ = pColor->red >> 8;
164             *pByte++ = pColor->green >> 8;
165             *pByte++ = pColor->blue >> 8;
166             }
167         }
168
169         /*  Create copyPixmap if required (copyPixmapDepth != 0).
170         */
171     if (pPriv->copyPixmapDepth) {
172         pPriv->copyPixmap = XCreatePixmap (pPriv->display, pPriv->drawable, pPriv->rect.width,
173                                            pPriv->stripHeight, pPriv->copyPixmapDepth);
174         if (!pPriv->copyPixmap)
175             return IL_ERROR_X_RESOURCE;
176         }
177
178     return IL_OK;
179 }
180
181         /*  ------------------------ ilReadXCleanup ------------------------------- */
182         /*  Cleanup() function for ilReadXDrawable() pipe elements.
183             Free anything in private that was created by Init().
184         */
185 static ilError ilReadXCleanup (
186     ilReadXPrivPtr      pPriv
187     )
188 {
189     if (pPriv->copyPixmap) {
190         XFreePixmap (pPriv->display, pPriv->copyPixmap);
191         pPriv->copyPixmap = (Pixmap)0;
192         }
193     return IL_OK;
194 }
195
196         /*  ------------------------ ilReadXDestroy ------------------------------- */
197         /*  Destroy() function for ilReadXDrawable() pipe elements.
198             Free anything in private that was created when the element was added.
199         */
200 static ilError ilReadXDestroy (
201     ilReadXPrivPtr      pPriv
202     )
203 {
204     if (pPriv->pPalette)
205         IL_FREE (pPriv->pPalette);
206     if (pPriv->grayMapImage)
207         ilDestroyObject (pPriv->grayMapImage);
208     return IL_OK;
209 }
210
211
212
213         /*  ------------------------ ilReadXExecute ------------------------------- */
214         /*  Execute() function for ilReadXDrawable() pipe elements.
215         */
216 static ilError ilReadXExecute (
217     ilExecuteData          *pData,
218     long                    dstLine,
219     long                   *pNLines
220     )
221 {
222 register ilReadXPrivPtr     pPriv;
223 Drawable                    readDrawable;
224 ilBool                      lastStrip;
225 long                        nLines;
226 int                         srcX, srcY;
227 XImage                     *Ximage;
228 ilPtr                       pSrcLine, pDstLine;
229 long                        srcRowBytes, dstRowBytes, nBytesToCopy;
230
231         /*  Read pPriv->stripHeight lines from the drawable, but if that takes
232             us off the end, read less, and note that this is lastStrip.
233         */
234     pPriv = (ilReadXPrivPtr)pData->pPrivate;
235     if ((pData->srcLine + pPriv->stripHeight) >= pPriv->rect.height) {
236         nLines = pPriv->rect.height - pData->srcLine;
237         lastStrip = TRUE;
238         }
239     else {
240         nLines = pPriv->stripHeight;
241         lastStrip = FALSE;
242         }
243     if (nLines <= 0)
244         return (lastStrip) ? IL_ERROR_LAST_STRIP : IL_OK;
245
246         /*  If "copyPixmap" non-null, blt from drawable into it at (0,0), and set src (X,Y)
247             to (0,0) - always GetImage() from left-top of it.  Then XGetImage() "nLines" 
248             from readDrawable (drawable or pixmap), and copy the bits into pDstImage's 
249             buffer at (0, "dstLine").
250         */
251     if (pPriv->copyPixmap) {
252         XCopyArea (pPriv->display, pPriv->drawable, pPriv->copyPixmap, pPriv->copyGC, 
253             pPriv->rect.x, pPriv->rect.y + pData->srcLine, pPriv->rect.width, nLines, 0, 0);
254         readDrawable = pPriv->copyPixmap;
255         srcX = srcY = 0;
256         }
257     else {
258         readDrawable = pPriv->drawable;
259         srcX = pPriv->rect.x;
260         srcY = pPriv->rect.y + pData->srcLine;
261         }
262     Ximage = XGetImage (pPriv->display, readDrawable, srcX, srcY, pPriv->rect.width, 
263                         nLines, ~0, ZPixmap);
264     if (!Ximage)
265         return IL_ERROR_X_GET_IMAGE;
266
267         /*  Bump srcLine by # of lines gotten, and copy that many lines to pDstImage.
268             Set nBytesToCopy to lesser of src and dstRowBytes.
269         */
270     *pNLines = nLines;
271     pData->srcLine += nLines;
272     pSrcLine = (ilPtr)Ximage->data;
273     srcRowBytes = Ximage->bytes_per_line;
274     dstRowBytes = pData->pDstImage->plane[0].nBytesPerRow;
275     nBytesToCopy = (srcRowBytes < dstRowBytes) ? srcRowBytes : dstRowBytes;
276     pDstLine = pData->pDstImage->plane[0].pPixels + dstLine * dstRowBytes;
277
278         /*  If a long/pixel image, must extract IL RGB bytes from X long/pixel image.
279         */
280     if (pPriv->isLongImage) {
281         register ilPtr          pDst;
282         register unsigned long  temp, *pSrc;
283         register long           nLongsM1;
284
285         while (nLines-- > 0) {
286             pSrc = (unsigned long *)pSrcLine;
287             pSrcLine += srcRowBytes;
288             pDst = pDstLine;
289             pDstLine += dstRowBytes;
290             nLongsM1 = pPriv->rect.width - 1;   /* width > 0, from ilReadXDrawable() */
291             do {
292                 temp = *pSrc++;                 /* long = <unused,r,g,b> each 8 bits */
293                 *(pDst + 2) = temp;             /* red */
294                 temp >>= 8;
295                 *(pDst + 1) = temp;             /* green */
296                 temp >>= 8;
297                 *pDst = temp;                   /* blue */
298                 pDst += 3;                      /* next dst pixel */
299                 } while (--nLongsM1 >= 0);
300             }
301         }
302     else {
303             /*  Byte or bit/pixel: if 1 bit/pixel image and LSBFirst bit order, reverse
304                 the bits using lookup table, else copy: if bytes/row same for X/IL images,
305                  copy buffer, else one line at a time.
306             */
307         if ((Ximage->depth == 1) && (Ximage->bitmap_bit_order == LSBFirst)) {
308             register ilPtr          pSrc, pDst;
309             register long           nBytesM1;
310
311             if (nBytesToCopy > 0)
312                 while (nLines-- > 0) {
313                     pSrc = pSrcLine;
314                     pSrcLine += srcRowBytes;
315                     pDst = pDstLine;
316                     pDstLine += dstRowBytes;
317                     nBytesM1 = nBytesToCopy - 1;
318                     do {
319                         *pDst++ = ilBitReverseTable[*pSrc++];
320                         } while (--nBytesM1 >= 0);
321                     }
322             }
323         else {
324             if (srcRowBytes == dstRowBytes)
325                 bcopy ((char *)pSrcLine, (char *)pDstLine, nLines * srcRowBytes);
326             else {
327                 while (nLines-- > 0) {
328                     bcopy ((char *)pSrcLine, (char *)pDstLine, nBytesToCopy);
329                     pSrcLine += srcRowBytes;
330                     pDstLine += dstRowBytes;
331                     }
332                 }
333             }
334         }
335
336     XDestroyImage (Ximage);
337     return (lastStrip) ? IL_ERROR_LAST_STRIP : IL_OK;
338 }
339
340
341
342         /*  ------------------------ ilReadXExecuteSlow ------------------------------- */
343         /*  Execute() function for ilReadXDrawable() pipe elements.
344         */
345 static ilError ilReadXExecuteSlow (
346     ilExecuteData          *pData,
347     long                    dstLine,
348     long                   *pNLines
349     )
350 {
351 register ilReadXPrivPtr     pPriv;
352 ilReadXPrivRec              priv;  
353 Drawable                    readDrawable;
354 ilBool                      lastStrip;
355 long                        nLines;
356 int                         srcX, srcY;
357 XImage                      *Ximage;
358 ilPtr                       pSrcLine, pDstLine;
359 long                        srcRowBytes, dstRowBytes, nBytesToCopy;
360
361         /*  Read pPriv->stripHeight lines from the drawable, but if that takes
362             us off the end, read less, and note that this is lastStrip.
363         */
364     pPriv = (ilReadXPrivPtr)pData->pPrivate;
365     if ((pData->srcLine + pPriv->stripHeight) >= pPriv->rect.height) {
366         nLines = pPriv->rect.height - pData->srcLine;
367         lastStrip = TRUE;
368         }
369     else {
370         nLines = pPriv->stripHeight;
371         lastStrip = FALSE;
372         }
373     if (nLines <= 0)
374         return (lastStrip) ? IL_ERROR_LAST_STRIP : IL_OK;
375
376         /*  If "copyPixmap" non-null, blt from drawable into it at (0,0), and set src (X,Y)
377             to (0,0) - always GetImage() from left-top of it.  Then XGetImage() "nLines" 
378             from readDrawable (drawable or pixmap), and copy the bits into pDstImage's 
379             buffer at (0, "dstLine").
380         */
381     if (pPriv->copyPixmap) {
382         XCopyArea (pPriv->display, pPriv->drawable, pPriv->copyPixmap, pPriv->copyGC, 
383             pPriv->rect.x, pPriv->rect.y + pData->srcLine, pPriv->rect.width, nLines, 0, 0);
384         readDrawable = pPriv->copyPixmap;
385         srcX = srcY = 0;
386         }
387     else {
388         readDrawable = pPriv->drawable;
389         srcX = pPriv->rect.x;
390         srcY = pPriv->rect.y + pData->srcLine;
391         }
392     Ximage = XGetImage (pPriv->display, readDrawable, srcX, srcY, pPriv->rect.width, 
393                         nLines, ~0, ZPixmap);
394     if (!Ximage)
395         return IL_ERROR_X_GET_IMAGE;
396
397         /*  Bump srcLine by # of lines gotten, and copy that many lines to pDstImage.
398             Set nBytesToCopy to lesser of src and dstRowBytes.
399         */
400     *pNLines = nLines;
401     pData->srcLine += nLines;
402     pSrcLine = (ilPtr)Ximage->data;
403     srcRowBytes = Ximage->bytes_per_line;
404     dstRowBytes = pData->pDstImage->plane[0].nBytesPerRow;
405     nBytesToCopy = (srcRowBytes < dstRowBytes) ? srcRowBytes : dstRowBytes;
406     pDstLine = pData->pDstImage->plane[0].pPixels + dstLine * dstRowBytes;
407
408         /*  If a long/pixel image, must extract IL RGB bytes from X long/pixel image.
409         */
410     if (pPriv->isLongImage) {
411         register ilPtr          pDst;
412         register unsigned long  temp, *pSrc;
413         register long           nLongsM1;
414         unsigned int            X, Y;
415
416         XVisualInfo             *pVisualInfo;
417         unsigned int            pixel;
418         int                     bit, count;
419 /************* slow pixel code*****************/
420                
421             if (((pPriv->nRedOnes <= 8) && (pPriv->nRedOnes >= 1)) 
422                   && ((pPriv->nGreenOnes <= 8) && (pPriv->nGreenOnes >= 1)) 
423                   && ((pPriv->nBlueOnes <= 8) && (pPriv->nBlueOnes >= 1))) {   
424            
425                for ( Y = 0; Y < nLines; Y++) {
426                 pDst = pDstLine;
427                 pDstLine += dstRowBytes;
428                 for ( X = 0 ; X < pPriv->rect.width; X++) {
429                   pixel = XGetPixel(Ximage, X, Y );
430                  /* Red */
431                   *pDst++ = (pixel & pPriv->OrgRedMask) >> pPriv->nRedZeros;
432                   /* Green */
433                   *pDst++ = (pixel & pPriv->OrgGreenMask) >> pPriv->nGreenZeros; 
434                   /* Blue */
435                  *pDst++ = (pixel & pPriv->OrgBlueMask) >> pPriv->nBlueZeros;
436                  
437                 }
438              }
439           }
440         }
441     
442      
443     else {
444             /*  Byte or bit/pixel: if 1 bit/pixel image and LSBFirst bit order, reverse
445                 the bits using lookup table, else copy: if bytes/row same for X/IL images,
446                  copy buffer, else one line at a time.
447             */
448         if ((Ximage->depth == 1) && (Ximage->bitmap_bit_order == LSBFirst)) {
449             register ilPtr          pSrc, pDst;
450             register long           nBytesM1;
451
452             if (nBytesToCopy > 0)
453                 while (nLines-- > 0) {
454                     pSrc = pSrcLine;
455                     pSrcLine += srcRowBytes;
456                     pDst = pDstLine;
457                     pDstLine += dstRowBytes;
458                     nBytesM1 = nBytesToCopy - 1;
459                     do {
460                         *pDst++ = ilBitReverseTable[*pSrc++];
461                         } while (--nBytesM1 >= 0);
462                     }
463             }
464         else {
465             if (srcRowBytes == dstRowBytes)
466                 bcopy ((char *)pSrcLine, (char *)pDstLine, nLines * srcRowBytes);
467             else {
468                 while (nLines-- > 0) {
469                     bcopy ((char *)pSrcLine, (char *)pDstLine, nBytesToCopy);
470                     pSrcLine += srcRowBytes;
471                     pDstLine += dstRowBytes;
472                     }
473                 }
474             }
475         }
476
477     XDestroyImage (Ximage);
478     return (lastStrip) ? IL_ERROR_LAST_STRIP : IL_OK;
479 }
480
481
482         /*  ------------------------ ilReadXDrawable ---------------------------- */
483         /*  Public function; see spec.
484         */
485 ilBool ilReadXDrawable (
486     ilPipe                  pipe,
487     Display                *display,
488     Drawable                drawable,
489     Visual                 *visual,
490     Colormap                colormap,
491     ilBool                  blackIsZero,
492     ilRect                 *pSrcRect,
493     ilBool                  copyToPixmap,
494     unsigned long           flags
495     )
496 {
497 ilReadXPrivRec              priv;           /* pre-inited private block; becomes *pPriv */
498 ilPipeInfo                  info;
499 ilImageDes                  des;
500 ilImageFormat               format;
501 ilError                     error;
502 int                         pixelSize, notUsed;
503 ilDstElementData            dstData;
504 XVisualInfo                 template, *pVisualInfo;
505 ilReadXPrivPtr              pPriv;
506 Window                      root;
507 int                         x, y;
508 unsigned int                border_width;
509 unsigned int                width, height, depth;   /* values for drawable */
510 Bool                        SlowMode = FALSE;
511 unsigned int                pixel;
512 int                         bit, count, nRedZeros, nGreenZeros, nBlueZeros;
513 int                         nRedOnes, nGreenOnes, nBlueOnes;
514 int                         RedMask, GreenMask, BlueMask;
515 /*int                         OrgRedMask, OrgGreenMask, OrgBlueMask;*/
516
517     if (pipe->objectType != IL_PIPE) {
518         pipe->context->error = IL_ERROR_OBJECT_TYPE;
519         return FALSE;
520         }
521     if (flags & ~1)
522         return ilDeclarePipeInvalid (pipe, IL_ERROR_PAR_NOT_ZERO);
523
524         /*  Get pipe info; if pipe not in IL_PIPE_EMPTY state: error.
525             Get width, height and depth of the requested drawable.
526         */
527     if (ilGetPipeInfo (pipe, FALSE, &info, &des, &format) != IL_PIPE_EMPTY) {
528         if (!pipe->context->error)
529             ilDeclarePipeInvalid (pipe, IL_ERROR_PIPE_STATE);
530         return FALSE;
531         }
532     if (!XGetGeometry (display, drawable, &root, &x, &y, &width, &height, 
533                        &border_width, &depth))
534         return ilDeclarePipeInvalid (pipe, IL_ERROR_X_DRAWABLE);
535
536         /*  Init priv with what we have so far. Set "priv.rect" to rectangle to read from 
537             drawable: bounds of drawable, intersected with pSrcRect if present.
538                 Null priv. objects - call ilReadXDestroy() on failure to free non-nulls.
539         */
540     priv.display = display;
541     priv.drawable = drawable;
542     priv.visual = visual;
543     priv.colormap = colormap;
544     priv.pPalette = (unsigned short *)NULL;
545     priv.grayMapImage = (ilClientImage)NULL;
546     priv.isLongImage = FALSE;
547     priv.rgbMapImage = (ilClientImage)NULL;
548     priv.rect.x = priv.rect.y = 0;
549     priv.rect.width = width;
550     priv.rect.height = height;
551     if (pSrcRect)
552         _ilIntersectRect (pSrcRect, &priv.rect);
553     if ((priv.rect.width <= 0) || (priv.rect.height <= 0))
554         return ilDeclarePipeInvalid (pipe, IL_ERROR_ZERO_SIZE_IMAGE);
555
556         /*  Do type-specific setup: set pixelSize based on des.type; set des and format.
557             If no visual or colormap: if not depth 1, error; else a bitmap: handle here.
558         */
559     if (!visual || !colormap) {
560         if (depth != 1)                                         /* not a bitmap */
561             return ilDeclarePipeInvalid (pipe, IL_ERROR_X_COLORMAP_VISUAL);
562
563         des = *IL_DES_BITONAL;
564         des.blackIsZero = blackIsZero;
565         format = *IL_FORMAT_BIT;
566         pixelSize = 1;
567         }
568     else {
569             /*  Not a bitmap: get info from "visual"; depths must match.
570                 Set "supported" true if this visual handled, else break (becomes error).
571             */
572         if (!colormap || !visual)
573             return ilDeclarePipeInvalid (pipe, IL_ERROR_X_COLORMAP_VISUAL);
574
575         template.visualid = XVisualIDFromVisual (visual);
576         pVisualInfo = XGetVisualInfo (display, VisualIDMask, &template, &notUsed);
577         if (!pVisualInfo)
578             return ilDeclarePipeInvalid (pipe, IL_ERROR_X_RESOURCE);
579         if (pVisualInfo->depth != depth)
580             return ilDeclarePipeInvalid (pipe, IL_ERROR_UNSUPPORTED_VISUAL);
581         priv.colormapSize = pVisualInfo->colormap_size;
582
583         switch (pVisualInfo->class) {
584
585                 /*  Support 1 and 8 bit gray scale.  For 1 bit, query color map to 
586                     determine blackIsZero (assume is if pixel 0 = rgb of 0,0,0.)
587                     For 8 bit, add an ilMap() element using pPriv->grayMapImage, which
588                     is setup in ilReadXInit() with the gray value for each X pixel.
589                     However, skip this step if rawMode.
590                 */
591             case GrayScale:
592             case StaticGray:
593                 if (depth == 1) {
594                     XColor color;
595
596                     color.pixel = 0;
597                     XQueryColor (display, colormap, &color);
598                     des = *IL_DES_BITONAL;
599                     des.blackIsZero = (!color.red && !color.green && !color.blue);
600                     format = *IL_FORMAT_BIT;
601                     pixelSize = 1;
602                     priv.SlowMode = SlowMode;
603                     }
604                 else if ((depth <= 8) && (depth > 1)) {
605                     ilImageInfo     imageInfo, *pImageInfo;
606
607                     if (!(flags & IL_READ_X_RAW_MODE)) {
608                         imageInfo.pDes = IL_DES_GRAY;
609                         imageInfo.pFormat = IL_FORMAT_BYTE;
610                         imageInfo.width = 256;
611                         imageInfo.height = 1;
612                         imageInfo.clientPixels = FALSE;
613                         priv.grayMapImage = ilCreateClientImage (pipe->context, 
614                                                                  &imageInfo, 0);
615                         if (!priv.grayMapImage)
616                             return FALSE;
617                         ilQueryClientImage (priv.grayMapImage, &pImageInfo, 0);
618                         priv.pGrayMapPixels = pImageInfo->plane[0].pPixels;
619                         }
620                     des = *IL_DES_GRAY;
621                     format = *IL_FORMAT_BYTE;
622                     pixelSize = 8;
623
624                     }
625                 
626                 else return ilDeclarePipeInvalid (pipe, IL_ERROR_UNSUPPORTED_VISUAL);
627                   SlowMode = depth < 8;
628                   priv.SlowMode = SlowMode;
629                 break;
630
631                 /*  Support 8 bit Pseudo/StaticColor as palette image; alloc palette. */
632             case StaticColor:
633             case PseudoColor:
634                 if (depth > 8)
635                     return ilDeclarePipeInvalid (pipe, IL_ERROR_UNSUPPORTED_VISUAL);
636
637                 des = *IL_DES_GRAY;
638                 des.type = IL_PALETTE;
639                 des.blackIsZero = FALSE;
640                 format = *IL_FORMAT_BYTE;
641                 pixelSize = 8;
642                if (!(priv.pPalette = (unsigned short *)
643                         IL_MALLOC_ZERO (sizeof(unsigned short) * (3 * 256))))
644                     return ilDeclarePipeInvalid (pipe, IL_ERROR_MALLOC);
645                     SlowMode = depth < 8;
646                     priv.SlowMode = SlowMode;
647                     
648                 break;
649
650                /*  Support True/DirectColor only if format = "<unused 8><8R><8G><8B>". */
651             case DirectColor:
652             case TrueColor:
653                 if ((depth == 24)
654                  && (pVisualInfo->red_mask == 0xff0000)
655                  && (pVisualInfo->green_mask == 0xff00)
656                  && (pVisualInfo->blue_mask == 0xff)) {
657                     ilImageInfo     imageInfo, *pImageInfo;
658
659                     if (!(flags & IL_READ_X_RAW_MODE)) {
660                         imageInfo.pDes = IL_DES_RGB;
661                         imageInfo.pFormat = IL_FORMAT_3BYTE_PIXEL;
662                         imageInfo.width = 256;
663                         imageInfo.height = 1;
664                         imageInfo.clientPixels = FALSE;
665                         priv.rgbMapImage = ilCreateClientImage (pipe->context, 
666                                                                 &imageInfo, 0);
667                         if (!priv.rgbMapImage)
668                             return FALSE;
669                         ilQueryClientImage (priv.rgbMapImage, &pImageInfo, 0);
670                         priv.pRGBMapPixels = pImageInfo->plane[0].pPixels;
671                         }
672                     des = *IL_DES_RGB;
673                     format = *IL_FORMAT_3BYTE_PIXEL;
674                     pixelSize = 24;
675                     priv.isLongImage = TRUE;
676                     priv.SlowMode = SlowMode;
677                     }
678                     
679                /*suport for Gacko and 12 bit display depth */
680
681               else { 
682
683                /*counting the number of ones and zeros in each red, 
684                  green and blue mask */
685                /* calculating Number of zeros and ones for red_mask */
686                /******************************************************/
687                  priv.OrgRedMask = pVisualInfo->red_mask;
688                  RedMask = pVisualInfo->red_mask;
689                  bit = 1;
690                  nRedOnes = 0;
691                      while(bit<0xffffff) {
692                        if (RedMask & bit) nRedOnes++;
693                        bit <<= 1;
694                      }
695                       
696             /*     nRedZeros = 8 - nRedOnes;
697                  priv.nRedZeros = nRedZeros; */
698                  priv.nRedOnes = nRedOnes;
699
700
701                  bit = 1;
702                  count = 0;
703                      while(!(RedMask & bit)){
704                        count++;
705                        RedMask >>= 1;
706                       }
707                  nRedZeros = count;
708                  priv.nRedZeros = nRedZeros;
709
710
711                  
712
713                  /* calculating Number of zeros and ones for Green_mask */
714                  /*******************************************************/
715                  priv.OrgGreenMask = pVisualInfo->green_mask;
716                  GreenMask = pVisualInfo->green_mask;
717                  bit = 1;
718                  nGreenOnes = 0;
719                      while(bit<0xffffff) {
720                        if (GreenMask & bit) nGreenOnes++;
721                        bit <<= 1;
722                      }
723             /*     nGreenZeros = 8 - nGreenOnes;
724                  priv.nGreenZeros = nGreenZeros; */
725                  priv.nGreenOnes = nGreenOnes;
726
727                  bit = 1;
728                  count = 0;
729                      while(!(GreenMask & bit )){
730                        count++;
731                        GreenMask >>= 1;
732                       }
733                  nGreenZeros = count;
734                  priv.nGreenZeros = nGreenZeros;
735
736
737
738
739                /* calculating Number of zeros and ones for blue_mask */
740                /******************************************************/
741                  priv.OrgBlueMask = pVisualInfo->blue_mask;
742                  BlueMask = pVisualInfo->blue_mask;
743                  bit = 1;
744                  nBlueOnes = 0;
745                      while(bit<0xffffff) {
746                        if (BlueMask & bit) nBlueOnes++;
747                        bit <<= 1;
748                      }
749                /*  nBlueZeros = 8 - nBlueOnes;
750                  priv.nBlueZeros = nBlueZeros; */
751                  priv.nBlueOnes = nBlueOnes;
752
753                  bit = 1;
754                  count = 0;
755                      while(!(BlueMask & bit)){
756                        count++;
757                        BlueMask >>= 1;
758                       }
759                  nBlueZeros = count;
760                  priv.nBlueZeros = nBlueZeros;
761
762
763
764
765                  if ((depth <=32)
766                   &&((nRedOnes <= 8) && (nRedOnes >= 1)) 
767                   &&((nGreenOnes <= 8) && (nGreenOnes >= 1)) 
768                   &&((nBlueOnes <= 8) && (nBlueOnes >= 1))) {
769                 
770                  ilImageInfo     imageInfo, *pImageInfo;
771
772                     if (!(flags & IL_READ_X_RAW_MODE)) {
773                         imageInfo.pDes = IL_DES_RGB;
774                         imageInfo.pFormat = IL_FORMAT_3BYTE_PIXEL;
775                         imageInfo.width = 256;
776                         imageInfo.height = 1;
777                         imageInfo.clientPixels = FALSE;
778                         priv.rgbMapImage = ilCreateClientImage (pipe->context, 
779                                                                 &imageInfo, 0);
780                         if (!priv.rgbMapImage)
781                             return FALSE;
782                         ilQueryClientImage (priv.rgbMapImage, &pImageInfo, 0);
783                         priv.pRGBMapPixels = pImageInfo->plane[0].pPixels;
784                         }
785                     des = *IL_DES_RGB;
786                     format = *IL_FORMAT_3BYTE_PIXEL;
787                     pixelSize = 24;
788                     priv.isLongImage = TRUE;
789                     SlowMode = depth<= 32;                
790                     priv.SlowMode = SlowMode; 
791
792                     }
793                
794                 else return ilDeclarePipeInvalid (pipe, IL_ERROR_UNSUPPORTED_VISUAL);
795
796                 }   
797                /* SlowMode = depth<= 32;                
798                 pPriv.SlowMode = SlowMode;*/
799                 break;
800             }   /* END switch visual class */
801         }       /* END not a bitmap */
802       
803         /*  Visual (or a bitmap) supported; read in strips to conserve memory. */
804     priv.stripHeight = ilRecommendedStripHeight (&des, &format, priv.rect.width, 
805                                                  priv.rect.height);
806
807         /*  Create a GC if copyToPixmap (set copyPixmapDepth != 0).  Null ptrs
808             out and call ilReadXDestroy() if failure - it will free non-null objects.
809         */
810     priv.copyPixmap = (Pixmap)0;
811     priv.copyPixmapDepth = 0;
812     priv.copyGC = (GC)NULL;
813     if (copyToPixmap) {
814         XGCValues   values;
815         values.subwindow_mode = IncludeInferiors;       /* get subwindow contents */
816         priv.copyGC = XCreateGC (priv.display, priv.drawable, GCSubwindowMode, &values);
817         if (!priv.copyGC) {
818             ilReadXDestroy (&priv);
819             return ilDeclarePipeInvalid (pipe, IL_ERROR_X_RESOURCE);
820             }
821         priv.copyPixmapDepth = depth;
822         }
823
824         /*  Add a producer element to read from the X drawable; copy priv into *pPriv. */
825     dstData.producerObject = (ilObject)NULL;
826     dstData.pDes = &des;
827     dstData.pFormat = &format;
828     dstData.width = priv.rect.width;
829     dstData.height = priv.rect.height;
830     dstData.stripHeight = priv.stripHeight;
831     dstData.constantStrip = TRUE;
832     dstData.pPalette = priv.pPalette;
833     
834   
835     pPriv = (ilReadXPrivPtr)ilAddPipeElement (pipe, IL_PRODUCER, sizeof (ilReadXPrivRec),
836                 0, (ilSrcElementData *)NULL, &dstData, ilReadXInit, ilReadXCleanup,
837                 ilReadXDestroy, ((SlowMode)?ilReadXExecuteSlow:ilReadXExecute), 0);
838                 
839   
840 /*    
841     pPriv = (ilReadXPrivPtr)ilAddPipeElement (pipe, IL_PRODUCER, sizeof (ilReadXPrivRec),
842                 0, (ilSrcElementData *)NULL, &dstData, ilReadXInit, ilReadXCleanup,
843                 ilReadXDestroy, ilReadXExecuteSlow, 0);
844                             
845 */                
846                 
847     if (!pPriv) {
848         ilReadXDestroy (&priv);
849         return FALSE;
850         }
851     *pPriv = priv;
852
853         /*  If a gray/rgbMapImage, use ilMap() to remap from colormap values. */
854     if (priv.grayMapImage)
855         return ilMap (pipe, priv.grayMapImage);
856     else if (priv.rgbMapImage)
857         return ilMap (pipe, priv.rgbMapImage);
858
859     pipe->context->error = IL_OK;
860     return TRUE;
861 }
862
863
864
865
866
867
868
869
870
871