cdesktopenv/cde/lib/DtHelp/il/ilreadX.c

872 lines
34 KiB
C

/*
* 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 <math.h>
#include <X11/Xutil.h>
#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 = <unused,r,g,b> 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, &notUsed);
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 = "<unused 8><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;
}