/* * CDE - Common Desktop Environment * * Copyright (c) 1993-2012, The Open Group. All rights reserved. * * These libraries and programs are free software; you can * redistribute them and/or modify them under the terms of the GNU * Lesser General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * These libraries and programs are distributed in the hope that * they will be useful, but WITHOUT ANY WARRANTY; without even the * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public * License along with these libraries and programs; if not, write * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth * Floor, Boston, MA 02110-1301 USA */ /* $XConsortium: ilreadX.c /main/3 1995/10/23 15:59:17 rswiston $ */ /**--------------------------------------------------------------------- *** *** (c)Copyright 1991 Hewlett-Packard Co. *** *** RESTRICTED RIGHTS LEGEND *** Use, duplication, or disclosure by the U.S. Government is subject to *** restrictions as set forth in sub-paragraph (c)(1)(ii) of the Rights in *** Technical Data and Computer Software clause in DFARS 252.227-7013. *** Hewlett-Packard Company *** 3000 Hanover Street *** Palo Alto, CA 94304 U.S.A. *** Rights for non-DOD U.S. Government Departments and Agencies are as set *** forth in FAR 52.227-19(c)(1,2). *** ***-------------------------------------------------------------------*/ #include "ilint.h" #include "ilcontext.h" #include "ilX.h" #include #include #include "ilpipelem.h" #include "ilerrors.h" /* Bit-flip table, in /ilc/ildata.c */ extern const unsigned char ilBitReverseTable []; /* Private data for all ilReadXDrawable() pipe functions. */ typedef struct { Display *display; /* copy of X display ptr */ Drawable drawable; /* given to / derived by ilReadXDrawable() */ Visual *visual; /* ptr to visual or null if a bitmap */ Colormap colormap; /* ptr to colormap or null if a bitmap */ int colormapSize; /* # of entries in the colormap */ unsigned short *pPalette; /* palette for Pseudo/StaticColor or null */ ilClientImage grayMapImage; /* ilMap() image for gray or null */ ilPtr pGrayMapPixels; /* ptr to pixels in grayMapImage if non-null */ ilBool isLongImage; /* long/pixel format (24 bit drawable) */ ilClientImage rgbMapImage; /* ilMap() image for rgb or null */ ilPtr pRGBMapPixels; /* ptr to pixels in rgbMapImage if non-null */ ilRect rect; /* piece of X image to read */ long stripHeight; /* height of each piece of drawable to read */ int copyPixmapDepth; /* depth for copyPixmap, or 0 => don't create */ Pixmap copyPixmap; /* pixmap to copy to/GetImage() from or null */ GC copyGC; /* GC to use to copy to "copyPixmap" */ int nRedOnes; int nGreenOnes; int nBlueOnes; int nRedZeros; int nGreenZeros; int nBlueZeros; Bool SlowMode; int OrgRedMask; int OrgGreenMask; int OrgBlueMask; } ilReadXPrivRec, *ilReadXPrivPtr; /* ------------------------ ilReadXInit ------------------------------- */ /* Init() function for ilReadXDrawable() pipe elements. */ static ilError ilReadXInit ( ilReadXPrivPtr pPriv, ilImageInfo *pSrcImage, ilImageInfo *pDstImage ) { #define NCOLORS 256 #define NGRAYS 256 #define NRGBS 256 ilReadXPrivRec priv; /* Init the palette if present by querying the colormap, with # entries = pPriv->colormapSize (limit to NCOLORS; may be less, so init unused to black). */ if (pPriv->pPalette) { int i; XColor cells [NCOLORS], *pColor; unsigned short *pPalette; for (i = 0, pColor = cells; i < NCOLORS; i++, pColor++) { pColor->red = pColor->green = pColor->blue = 0; pColor->pixel = i; } XQueryColors (pPriv->display, pPriv->colormap, cells, (pPriv->colormapSize > NCOLORS) ? NCOLORS : pPriv->colormapSize); for (i = 0, pPalette = pPriv->pPalette, pColor = cells; i < NCOLORS; i++, pPalette++, pColor++) { pPalette[0*256] = pColor->red; pPalette[1*256] = pColor->green; pPalette[2*256] = pColor->blue; } } /* If a grayMapImage, reading from grayscale: query the colormap and store the upper 8 bits of the green value into grayMapImage, which is used by an ilMap() filter which follows the ilReadXDrawable() (added there). */ else if (pPriv->grayMapImage) { int i; XColor cells [NGRAYS], *pColor; ilPtr pByte; for (i = 0, pColor = cells; i < NGRAYS; i++, pColor++) { pColor->red = pColor->green = pColor->blue = 0; pColor->pixel = i; } XQueryColors (pPriv->display, pPriv->colormap, cells, (pPriv->colormapSize > NGRAYS) ? NGRAYS : pPriv->colormapSize); for (i = 0, pByte = pPriv->pGrayMapPixels, pColor = cells; i < NGRAYS; i++, pColor++) *pByte++ = pColor->green >> 8; } /* If an rgbMapImage, reading from True/DirectColor: query color - RGBs are independent. Init the mapImage which is 3 byte (rgb) per pixel. */ else if (pPriv->rgbMapImage) { int i; XColor cells [NRGBS], *pColor; ilPtr pByte; for (i = 0, pColor = cells; i < NRGBS; i++, pColor++) { if(!(pPriv->SlowMode)){ pColor->red = pColor->green = pColor->blue = 0; pColor->pixel = ((i << 16) | (i << 8) | i); } else { pColor->red = pColor->green = pColor->blue = 0; pColor->pixel = ((i << pPriv->nRedZeros) | (i << pPriv->nGreenZeros) | i << pPriv->nBlueZeros); } } XQueryColors (pPriv->display, pPriv->colormap, cells, (pPriv->colormapSize > NRGBS) ? NRGBS : pPriv->colormapSize); for (i = 0, pByte = pPriv->pRGBMapPixels, pColor = cells; i < NRGBS; i++, pColor++) { *pByte++ = pColor->red >> 8; *pByte++ = pColor->green >> 8; *pByte++ = pColor->blue >> 8; } } /* Create copyPixmap if required (copyPixmapDepth != 0). */ if (pPriv->copyPixmapDepth) { pPriv->copyPixmap = XCreatePixmap (pPriv->display, pPriv->drawable, pPriv->rect.width, pPriv->stripHeight, pPriv->copyPixmapDepth); if (!pPriv->copyPixmap) return IL_ERROR_X_RESOURCE; } return IL_OK; } /* ------------------------ ilReadXCleanup ------------------------------- */ /* Cleanup() function for ilReadXDrawable() pipe elements. Free anything in private that was created by Init(). */ static ilError ilReadXCleanup ( ilReadXPrivPtr pPriv ) { if (pPriv->copyPixmap) { XFreePixmap (pPriv->display, pPriv->copyPixmap); pPriv->copyPixmap = (Pixmap)0; } return IL_OK; } /* ------------------------ ilReadXDestroy ------------------------------- */ /* Destroy() function for ilReadXDrawable() pipe elements. Free anything in private that was created when the element was added. */ static ilError ilReadXDestroy ( ilReadXPrivPtr pPriv ) { if (pPriv->pPalette) IL_FREE (pPriv->pPalette); if (pPriv->grayMapImage) ilDestroyObject (pPriv->grayMapImage); return IL_OK; } /* ------------------------ ilReadXExecute ------------------------------- */ /* Execute() function for ilReadXDrawable() pipe elements. */ static ilError ilReadXExecute ( ilExecuteData *pData, long dstLine, long *pNLines ) { ilReadXPrivPtr pPriv; Drawable readDrawable; ilBool lastStrip; long nLines; int srcX, srcY; XImage *Ximage; ilPtr pSrcLine, pDstLine; long srcRowBytes, dstRowBytes, nBytesToCopy; /* Read pPriv->stripHeight lines from the drawable, but if that takes us off the end, read less, and note that this is lastStrip. */ pPriv = (ilReadXPrivPtr)pData->pPrivate; if ((pData->srcLine + pPriv->stripHeight) >= pPriv->rect.height) { nLines = pPriv->rect.height - pData->srcLine; lastStrip = TRUE; } else { nLines = pPriv->stripHeight; lastStrip = FALSE; } if (nLines <= 0) return (lastStrip) ? IL_ERROR_LAST_STRIP : IL_OK; /* If "copyPixmap" non-null, blt from drawable into it at (0,0), and set src (X,Y) to (0,0) - always GetImage() from left-top of it. Then XGetImage() "nLines" from readDrawable (drawable or pixmap), and copy the bits into pDstImage's buffer at (0, "dstLine"). */ if (pPriv->copyPixmap) { XCopyArea (pPriv->display, pPriv->drawable, pPriv->copyPixmap, pPriv->copyGC, pPriv->rect.x, pPriv->rect.y + pData->srcLine, pPriv->rect.width, nLines, 0, 0); readDrawable = pPriv->copyPixmap; srcX = srcY = 0; } else { readDrawable = pPriv->drawable; srcX = pPriv->rect.x; srcY = pPriv->rect.y + pData->srcLine; } Ximage = XGetImage (pPriv->display, readDrawable, srcX, srcY, pPriv->rect.width, nLines, ~0, ZPixmap); if (!Ximage) return IL_ERROR_X_GET_IMAGE; /* Bump srcLine by # of lines gotten, and copy that many lines to pDstImage. Set nBytesToCopy to lesser of src and dstRowBytes. */ *pNLines = nLines; pData->srcLine += nLines; pSrcLine = (ilPtr)Ximage->data; srcRowBytes = Ximage->bytes_per_line; dstRowBytes = pData->pDstImage->plane[0].nBytesPerRow; nBytesToCopy = (srcRowBytes < dstRowBytes) ? srcRowBytes : dstRowBytes; pDstLine = pData->pDstImage->plane[0].pPixels + dstLine * dstRowBytes; /* If a long/pixel image, must extract IL RGB bytes from X long/pixel image. */ if (pPriv->isLongImage) { ilPtr pDst; unsigned long temp, *pSrc; long nLongsM1; while (nLines-- > 0) { pSrc = (unsigned long *)pSrcLine; pSrcLine += srcRowBytes; pDst = pDstLine; pDstLine += dstRowBytes; nLongsM1 = pPriv->rect.width - 1; /* width > 0, from ilReadXDrawable() */ do { temp = *pSrc++; /* long = each 8 bits */ *(pDst + 2) = temp; /* red */ temp >>= 8; *(pDst + 1) = temp; /* green */ temp >>= 8; *pDst = temp; /* blue */ pDst += 3; /* next dst pixel */ } while (--nLongsM1 >= 0); } } else { /* Byte or bit/pixel: if 1 bit/pixel image and LSBFirst bit order, reverse the bits using lookup table, else copy: if bytes/row same for X/IL images, copy buffer, else one line at a time. */ if ((Ximage->depth == 1) && (Ximage->bitmap_bit_order == LSBFirst)) { ilPtr pSrc, pDst; long nBytesM1; if (nBytesToCopy > 0) while (nLines-- > 0) { pSrc = pSrcLine; pSrcLine += srcRowBytes; pDst = pDstLine; pDstLine += dstRowBytes; nBytesM1 = nBytesToCopy - 1; do { *pDst++ = ilBitReverseTable[*pSrc++]; } while (--nBytesM1 >= 0); } } else { if (srcRowBytes == dstRowBytes) bcopy ((char *)pSrcLine, (char *)pDstLine, nLines * srcRowBytes); else { while (nLines-- > 0) { bcopy ((char *)pSrcLine, (char *)pDstLine, nBytesToCopy); pSrcLine += srcRowBytes; pDstLine += dstRowBytes; } } } } XDestroyImage (Ximage); return (lastStrip) ? IL_ERROR_LAST_STRIP : IL_OK; } /* ------------------------ ilReadXExecuteSlow ------------------------------- */ /* Execute() function for ilReadXDrawable() pipe elements. */ static ilError ilReadXExecuteSlow ( ilExecuteData *pData, long dstLine, long *pNLines ) { ilReadXPrivPtr pPriv; ilReadXPrivRec priv; Drawable readDrawable; ilBool lastStrip; long nLines; int srcX, srcY; XImage *Ximage; ilPtr pSrcLine, pDstLine; long srcRowBytes, dstRowBytes, nBytesToCopy; /* Read pPriv->stripHeight lines from the drawable, but if that takes us off the end, read less, and note that this is lastStrip. */ pPriv = (ilReadXPrivPtr)pData->pPrivate; if ((pData->srcLine + pPriv->stripHeight) >= pPriv->rect.height) { nLines = pPriv->rect.height - pData->srcLine; lastStrip = TRUE; } else { nLines = pPriv->stripHeight; lastStrip = FALSE; } if (nLines <= 0) return (lastStrip) ? IL_ERROR_LAST_STRIP : IL_OK; /* If "copyPixmap" non-null, blt from drawable into it at (0,0), and set src (X,Y) to (0,0) - always GetImage() from left-top of it. Then XGetImage() "nLines" from readDrawable (drawable or pixmap), and copy the bits into pDstImage's buffer at (0, "dstLine"). */ if (pPriv->copyPixmap) { XCopyArea (pPriv->display, pPriv->drawable, pPriv->copyPixmap, pPriv->copyGC, pPriv->rect.x, pPriv->rect.y + pData->srcLine, pPriv->rect.width, nLines, 0, 0); readDrawable = pPriv->copyPixmap; srcX = srcY = 0; } else { readDrawable = pPriv->drawable; srcX = pPriv->rect.x; srcY = pPriv->rect.y + pData->srcLine; } Ximage = XGetImage (pPriv->display, readDrawable, srcX, srcY, pPriv->rect.width, nLines, ~0, ZPixmap); if (!Ximage) return IL_ERROR_X_GET_IMAGE; /* Bump srcLine by # of lines gotten, and copy that many lines to pDstImage. Set nBytesToCopy to lesser of src and dstRowBytes. */ *pNLines = nLines; pData->srcLine += nLines; pSrcLine = (ilPtr)Ximage->data; srcRowBytes = Ximage->bytes_per_line; dstRowBytes = pData->pDstImage->plane[0].nBytesPerRow; nBytesToCopy = (srcRowBytes < dstRowBytes) ? srcRowBytes : dstRowBytes; pDstLine = pData->pDstImage->plane[0].pPixels + dstLine * dstRowBytes; /* If a long/pixel image, must extract IL RGB bytes from X long/pixel image. */ if (pPriv->isLongImage) { ilPtr pDst; unsigned long temp, *pSrc; long nLongsM1; unsigned int X, Y; XVisualInfo *pVisualInfo; unsigned int pixel; int bit, count; /************* slow pixel code*****************/ if (((pPriv->nRedOnes <= 8) && (pPriv->nRedOnes >= 1)) && ((pPriv->nGreenOnes <= 8) && (pPriv->nGreenOnes >= 1)) && ((pPriv->nBlueOnes <= 8) && (pPriv->nBlueOnes >= 1))) { for ( Y = 0; Y < nLines; Y++) { pDst = pDstLine; pDstLine += dstRowBytes; for ( X = 0 ; X < pPriv->rect.width; X++) { pixel = XGetPixel(Ximage, X, Y ); /* Red */ *pDst++ = (pixel & pPriv->OrgRedMask) >> pPriv->nRedZeros; /* Green */ *pDst++ = (pixel & pPriv->OrgGreenMask) >> pPriv->nGreenZeros; /* Blue */ *pDst++ = (pixel & pPriv->OrgBlueMask) >> pPriv->nBlueZeros; } } } } else { /* Byte or bit/pixel: if 1 bit/pixel image and LSBFirst bit order, reverse the bits using lookup table, else copy: if bytes/row same for X/IL images, copy buffer, else one line at a time. */ if ((Ximage->depth == 1) && (Ximage->bitmap_bit_order == LSBFirst)) { ilPtr pSrc, pDst; long nBytesM1; if (nBytesToCopy > 0) while (nLines-- > 0) { pSrc = pSrcLine; pSrcLine += srcRowBytes; pDst = pDstLine; pDstLine += dstRowBytes; nBytesM1 = nBytesToCopy - 1; do { *pDst++ = ilBitReverseTable[*pSrc++]; } while (--nBytesM1 >= 0); } } else { if (srcRowBytes == dstRowBytes) bcopy ((char *)pSrcLine, (char *)pDstLine, nLines * srcRowBytes); else { while (nLines-- > 0) { bcopy ((char *)pSrcLine, (char *)pDstLine, nBytesToCopy); pSrcLine += srcRowBytes; pDstLine += dstRowBytes; } } } } XDestroyImage (Ximage); return (lastStrip) ? IL_ERROR_LAST_STRIP : IL_OK; } /* ------------------------ ilReadXDrawable ---------------------------- */ /* Public function; see spec. */ ilBool ilReadXDrawable ( ilPipe pipe, Display *display, Drawable drawable, Visual *visual, Colormap colormap, ilBool blackIsZero, ilRect *pSrcRect, ilBool copyToPixmap, unsigned long flags ) { ilReadXPrivRec priv; /* pre-inited private block; becomes *pPriv */ ilPipeInfo info; ilImageDes des; ilImageFormat format; ilError error; int pixelSize, notUsed; ilDstElementData dstData; XVisualInfo template, *pVisualInfo; ilReadXPrivPtr pPriv; Window root; int x, y; unsigned int border_width; unsigned int width, height, depth; /* values for drawable */ Bool SlowMode = FALSE; unsigned int pixel; int bit, count, nRedZeros, nGreenZeros, nBlueZeros; int nRedOnes, nGreenOnes, nBlueOnes; int RedMask, GreenMask, BlueMask; /*int OrgRedMask, OrgGreenMask, OrgBlueMask;*/ if (pipe->objectType != IL_PIPE) { pipe->context->error = IL_ERROR_OBJECT_TYPE; return FALSE; } if (flags & ~1) return ilDeclarePipeInvalid (pipe, IL_ERROR_PAR_NOT_ZERO); /* Get pipe info; if pipe not in IL_PIPE_EMPTY state: error. Get width, height and depth of the requested drawable. */ if (ilGetPipeInfo (pipe, FALSE, &info, &des, &format) != IL_PIPE_EMPTY) { if (!pipe->context->error) ilDeclarePipeInvalid (pipe, IL_ERROR_PIPE_STATE); return FALSE; } if (!XGetGeometry (display, drawable, &root, &x, &y, &width, &height, &border_width, &depth)) return ilDeclarePipeInvalid (pipe, IL_ERROR_X_DRAWABLE); /* Init priv with what we have so far. Set "priv.rect" to rectangle to read from drawable: bounds of drawable, intersected with pSrcRect if present. Null priv. objects - call ilReadXDestroy() on failure to free non-nulls. */ priv.display = display; priv.drawable = drawable; priv.visual = visual; priv.colormap = colormap; priv.pPalette = (unsigned short *)NULL; priv.grayMapImage = (ilClientImage)NULL; priv.isLongImage = FALSE; priv.rgbMapImage = (ilClientImage)NULL; priv.rect.x = priv.rect.y = 0; priv.rect.width = width; priv.rect.height = height; if (pSrcRect) _ilIntersectRect (pSrcRect, &priv.rect); if ((priv.rect.width <= 0) || (priv.rect.height <= 0)) return ilDeclarePipeInvalid (pipe, IL_ERROR_ZERO_SIZE_IMAGE); /* Do type-specific setup: set pixelSize based on des.type; set des and format. If no visual or colormap: if not depth 1, error; else a bitmap: handle here. */ if (!visual || !colormap) { if (depth != 1) /* not a bitmap */ return ilDeclarePipeInvalid (pipe, IL_ERROR_X_COLORMAP_VISUAL); des = *IL_DES_BITONAL; des.blackIsZero = blackIsZero; format = *IL_FORMAT_BIT; pixelSize = 1; } else { /* Not a bitmap: get info from "visual"; depths must match. Set "supported" true if this visual handled, else break (becomes error). */ if (!colormap || !visual) return ilDeclarePipeInvalid (pipe, IL_ERROR_X_COLORMAP_VISUAL); template.visualid = XVisualIDFromVisual (visual); pVisualInfo = XGetVisualInfo (display, VisualIDMask, &template, ¬Used); if (!pVisualInfo) return ilDeclarePipeInvalid (pipe, IL_ERROR_X_RESOURCE); if (pVisualInfo->depth != depth) return ilDeclarePipeInvalid (pipe, IL_ERROR_UNSUPPORTED_VISUAL); priv.colormapSize = pVisualInfo->colormap_size; switch (pVisualInfo->class) { /* Support 1 and 8 bit gray scale. For 1 bit, query color map to determine blackIsZero (assume is if pixel 0 = rgb of 0,0,0.) For 8 bit, add an ilMap() element using pPriv->grayMapImage, which is setup in ilReadXInit() with the gray value for each X pixel. However, skip this step if rawMode. */ case GrayScale: case StaticGray: if (depth == 1) { XColor color; color.pixel = 0; XQueryColor (display, colormap, &color); des = *IL_DES_BITONAL; des.blackIsZero = (!color.red && !color.green && !color.blue); format = *IL_FORMAT_BIT; pixelSize = 1; priv.SlowMode = SlowMode; } else if ((depth <= 8) && (depth > 1)) { ilImageInfo imageInfo, *pImageInfo; if (!(flags & IL_READ_X_RAW_MODE)) { imageInfo.pDes = IL_DES_GRAY; imageInfo.pFormat = IL_FORMAT_BYTE; imageInfo.width = 256; imageInfo.height = 1; imageInfo.clientPixels = FALSE; priv.grayMapImage = ilCreateClientImage (pipe->context, &imageInfo, 0); if (!priv.grayMapImage) return FALSE; ilQueryClientImage (priv.grayMapImage, &pImageInfo, 0); priv.pGrayMapPixels = pImageInfo->plane[0].pPixels; } des = *IL_DES_GRAY; format = *IL_FORMAT_BYTE; pixelSize = 8; } else return ilDeclarePipeInvalid (pipe, IL_ERROR_UNSUPPORTED_VISUAL); SlowMode = depth < 8; priv.SlowMode = SlowMode; break; /* Support 8 bit Pseudo/StaticColor as palette image; alloc palette. */ case StaticColor: case PseudoColor: if (depth > 8) return ilDeclarePipeInvalid (pipe, IL_ERROR_UNSUPPORTED_VISUAL); des = *IL_DES_GRAY; des.type = IL_PALETTE; des.blackIsZero = FALSE; format = *IL_FORMAT_BYTE; pixelSize = 8; if (!(priv.pPalette = (unsigned short *) IL_MALLOC_ZERO (sizeof(unsigned short) * (3 * 256)))) return ilDeclarePipeInvalid (pipe, IL_ERROR_MALLOC); SlowMode = depth < 8; priv.SlowMode = SlowMode; break; /* Support True/DirectColor only if format = "<8R><8G><8B>". */ case DirectColor: case TrueColor: if ((depth == 24) && (pVisualInfo->red_mask == 0xff0000) && (pVisualInfo->green_mask == 0xff00) && (pVisualInfo->blue_mask == 0xff)) { ilImageInfo imageInfo, *pImageInfo; if (!(flags & IL_READ_X_RAW_MODE)) { imageInfo.pDes = IL_DES_RGB; imageInfo.pFormat = IL_FORMAT_3BYTE_PIXEL; imageInfo.width = 256; imageInfo.height = 1; imageInfo.clientPixels = FALSE; priv.rgbMapImage = ilCreateClientImage (pipe->context, &imageInfo, 0); if (!priv.rgbMapImage) return FALSE; ilQueryClientImage (priv.rgbMapImage, &pImageInfo, 0); priv.pRGBMapPixels = pImageInfo->plane[0].pPixels; } des = *IL_DES_RGB; format = *IL_FORMAT_3BYTE_PIXEL; pixelSize = 24; priv.isLongImage = TRUE; priv.SlowMode = SlowMode; } /*suport for Gacko and 12 bit display depth */ else { /*counting the number of ones and zeros in each red, green and blue mask */ /* calculating Number of zeros and ones for red_mask */ /******************************************************/ priv.OrgRedMask = pVisualInfo->red_mask; RedMask = pVisualInfo->red_mask; bit = 1; nRedOnes = 0; while(bit<0xffffff) { if (RedMask & bit) nRedOnes++; bit <<= 1; } /* nRedZeros = 8 - nRedOnes; priv.nRedZeros = nRedZeros; */ priv.nRedOnes = nRedOnes; bit = 1; count = 0; while(!(RedMask & bit)){ count++; RedMask >>= 1; } nRedZeros = count; priv.nRedZeros = nRedZeros; /* calculating Number of zeros and ones for Green_mask */ /*******************************************************/ priv.OrgGreenMask = pVisualInfo->green_mask; GreenMask = pVisualInfo->green_mask; bit = 1; nGreenOnes = 0; while(bit<0xffffff) { if (GreenMask & bit) nGreenOnes++; bit <<= 1; } /* nGreenZeros = 8 - nGreenOnes; priv.nGreenZeros = nGreenZeros; */ priv.nGreenOnes = nGreenOnes; bit = 1; count = 0; while(!(GreenMask & bit )){ count++; GreenMask >>= 1; } nGreenZeros = count; priv.nGreenZeros = nGreenZeros; /* calculating Number of zeros and ones for blue_mask */ /******************************************************/ priv.OrgBlueMask = pVisualInfo->blue_mask; BlueMask = pVisualInfo->blue_mask; bit = 1; nBlueOnes = 0; while(bit<0xffffff) { if (BlueMask & bit) nBlueOnes++; bit <<= 1; } /* nBlueZeros = 8 - nBlueOnes; priv.nBlueZeros = nBlueZeros; */ priv.nBlueOnes = nBlueOnes; bit = 1; count = 0; while(!(BlueMask & bit)){ count++; BlueMask >>= 1; } nBlueZeros = count; priv.nBlueZeros = nBlueZeros; if ((depth <=32) &&((nRedOnes <= 8) && (nRedOnes >= 1)) &&((nGreenOnes <= 8) && (nGreenOnes >= 1)) &&((nBlueOnes <= 8) && (nBlueOnes >= 1))) { ilImageInfo imageInfo, *pImageInfo; if (!(flags & IL_READ_X_RAW_MODE)) { imageInfo.pDes = IL_DES_RGB; imageInfo.pFormat = IL_FORMAT_3BYTE_PIXEL; imageInfo.width = 256; imageInfo.height = 1; imageInfo.clientPixels = FALSE; priv.rgbMapImage = ilCreateClientImage (pipe->context, &imageInfo, 0); if (!priv.rgbMapImage) return FALSE; ilQueryClientImage (priv.rgbMapImage, &pImageInfo, 0); priv.pRGBMapPixels = pImageInfo->plane[0].pPixels; } des = *IL_DES_RGB; format = *IL_FORMAT_3BYTE_PIXEL; pixelSize = 24; priv.isLongImage = TRUE; SlowMode = depth<= 32; priv.SlowMode = SlowMode; } else return ilDeclarePipeInvalid (pipe, IL_ERROR_UNSUPPORTED_VISUAL); } /* SlowMode = depth<= 32; pPriv.SlowMode = SlowMode;*/ break; } /* END switch visual class */ } /* END not a bitmap */ /* Visual (or a bitmap) supported; read in strips to conserve memory. */ priv.stripHeight = ilRecommendedStripHeight (&des, &format, priv.rect.width, priv.rect.height); /* Create a GC if copyToPixmap (set copyPixmapDepth != 0). Null ptrs out and call ilReadXDestroy() if failure - it will free non-null objects. */ priv.copyPixmap = (Pixmap)0; priv.copyPixmapDepth = 0; priv.copyGC = (GC)NULL; if (copyToPixmap) { XGCValues values; values.subwindow_mode = IncludeInferiors; /* get subwindow contents */ priv.copyGC = XCreateGC (priv.display, priv.drawable, GCSubwindowMode, &values); if (!priv.copyGC) { ilReadXDestroy (&priv); return ilDeclarePipeInvalid (pipe, IL_ERROR_X_RESOURCE); } priv.copyPixmapDepth = depth; } /* Add a producer element to read from the X drawable; copy priv into *pPriv. */ dstData.producerObject = (ilObject)NULL; dstData.pDes = &des; dstData.pFormat = &format; dstData.width = priv.rect.width; dstData.height = priv.rect.height; dstData.stripHeight = priv.stripHeight; dstData.constantStrip = TRUE; dstData.pPalette = priv.pPalette; pPriv = (ilReadXPrivPtr)ilAddPipeElement (pipe, IL_PRODUCER, sizeof (ilReadXPrivRec), 0, (ilSrcElementData *)NULL, &dstData, ilReadXInit, ilReadXCleanup, ilReadXDestroy, ((SlowMode)?ilReadXExecuteSlow:ilReadXExecute), 0); /* pPriv = (ilReadXPrivPtr)ilAddPipeElement (pipe, IL_PRODUCER, sizeof (ilReadXPrivRec), 0, (ilSrcElementData *)NULL, &dstData, ilReadXInit, ilReadXCleanup, ilReadXDestroy, ilReadXExecuteSlow, 0); */ if (!pPriv) { ilReadXDestroy (&priv); return FALSE; } *pPriv = priv; /* If a gray/rgbMapImage, use ilMap() to remap from colormap values. */ if (priv.grayMapImage) return ilMap (pipe, priv.grayMapImage); else if (priv.rgbMapImage) return ilMap (pipe, priv.rgbMapImage); pipe->context->error = IL_OK; return TRUE; }