ilreadX.c 34 KB

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