home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / evbl0627.zip / everblue_20010627.zip / x11 / Xlib_PutImage.c < prev    next >
C/C++ Source or Header  |  2000-10-11  |  27KB  |  862 lines

  1. /*
  2.  
  3. Copyright (c) 1986  X Consortium
  4.  
  5. Permission is hereby granted, free of charge, to any person obtaining a copy
  6. of this software and associated documentation files (the "Software"), to deal
  7. in the Software without restriction, including without limitation the rights
  8. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  9. copies of the Software, and to permit persons to whom the Software is
  10. furnished to do so, subject to the following conditions:
  11.  
  12. The above copyright notice and this permission notice shall be included in
  13. all copies or substantial portions of the Software.
  14.  
  15. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
  18. X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
  19. AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  20. CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  21.  
  22. Except as contained in this notice, the name of the X Consortium shall not be
  23. used in advertising or otherwise to promote the sale, use or other dealings
  24. in this Software without prior written authorization from the X Consortium.
  25.  
  26. */
  27.  
  28.  
  29. #include "Xlib_private.h"
  30. #include "X11/Xutil.h"
  31. #include <stdio.h>
  32. #include <alloca.h>
  33.  
  34. #ifdef __STDC__
  35. #define Const const
  36. #else
  37. #define Const /**/
  38. #endif
  39. #if defined(__STDC__) && ((defined(sun) && defined(SVR4)) || defined(WIN32))
  40. #define RConst /**/
  41. #else
  42. #define RConst Const
  43. #endif
  44.  
  45. #if defined(Lynx) && defined(ROUNDUP)
  46. #undef ROUNDUP
  47. #endif
  48.  
  49. /* assumes pad is a power of 2 */
  50. #define ROUNDUP(nbytes, pad) (((nbytes) + ((pad) - 1)) & ~(long)((pad) - 1))
  51.  
  52. static unsigned char Const _reverse_byte[0x100] = {
  53.     0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
  54.     0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
  55.     0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
  56.     0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
  57.     0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
  58.     0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
  59.     0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
  60.     0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
  61.     0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
  62.     0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
  63.     0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
  64.     0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
  65.     0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
  66.     0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
  67.     0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
  68.     0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
  69.     0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
  70.     0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
  71.     0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
  72.     0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
  73.     0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
  74.     0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
  75.     0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
  76.     0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
  77.     0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
  78.     0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
  79.     0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
  80.     0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
  81.     0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
  82.     0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
  83.     0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
  84.     0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff
  85. };
  86.  
  87. static unsigned char Const _reverse_nibs[0x100] = {
  88.     0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70,
  89.     0x80, 0x90, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0,
  90.     0x01, 0x11, 0x21, 0x31, 0x41, 0x51, 0x61, 0x71,
  91.     0x81, 0x91, 0xa1, 0xb1, 0xc1, 0xd1, 0xe1, 0xf1,
  92.     0x02, 0x12, 0x22, 0x32, 0x42, 0x52, 0x62, 0x72,
  93.     0x82, 0x92, 0xa2, 0xb2, 0xc2, 0xd2, 0xe2, 0xf2,
  94.     0x03, 0x13, 0x23, 0x33, 0x43, 0x53, 0x63, 0x73,
  95.     0x83, 0x93, 0xa3, 0xb3, 0xc3, 0xd3, 0xe3, 0xf3,
  96.     0x04, 0x14, 0x24, 0x34, 0x44, 0x54, 0x64, 0x74,
  97.     0x84, 0x94, 0xa4, 0xb4, 0xc4, 0xd4, 0xe4, 0xf4,
  98.     0x05, 0x15, 0x25, 0x35, 0x45, 0x55, 0x65, 0x75,
  99.     0x85, 0x95, 0xa5, 0xb5, 0xc5, 0xd5, 0xe5, 0xf5,
  100.     0x06, 0x16, 0x26, 0x36, 0x46, 0x56, 0x66, 0x76,
  101.     0x86, 0x96, 0xa6, 0xb6, 0xc6, 0xd6, 0xe6, 0xf6,
  102.     0x07, 0x17, 0x27, 0x37, 0x47, 0x57, 0x67, 0x77,
  103.     0x87, 0x97, 0xa7, 0xb7, 0xc7, 0xd7, 0xe7, 0xf7,
  104.     0x08, 0x18, 0x28, 0x38, 0x48, 0x58, 0x68, 0x78,
  105.     0x88, 0x98, 0xa8, 0xb8, 0xc8, 0xd8, 0xe8, 0xf8,
  106.     0x09, 0x19, 0x29, 0x39, 0x49, 0x59, 0x69, 0x79,
  107.     0x89, 0x99, 0xa9, 0xb9, 0xc9, 0xd9, 0xe9, 0xf9,
  108.     0x0a, 0x1a, 0x2a, 0x3a, 0x4a, 0x5a, 0x6a, 0x7a,
  109.     0x8a, 0x9a, 0xaa, 0xba, 0xca, 0xda, 0xea, 0xfa,
  110.     0x0b, 0x1b, 0x2b, 0x3b, 0x4b, 0x5b, 0x6b, 0x7b,
  111.     0x8b, 0x9b, 0xab, 0xbb, 0xcb, 0xdb, 0xeb, 0xfb,
  112.     0x0c, 0x1c, 0x2c, 0x3c, 0x4c, 0x5c, 0x6c, 0x7c,
  113.     0x8c, 0x9c, 0xac, 0xbc, 0xcc, 0xdc, 0xec, 0xfc,
  114.     0x0d, 0x1d, 0x2d, 0x3d, 0x4d, 0x5d, 0x6d, 0x7d,
  115.     0x8d, 0x9d, 0xad, 0xbd, 0xcd, 0xdd, 0xed, 0xfd,
  116.     0x0e, 0x1e, 0x2e, 0x3e, 0x4e, 0x5e, 0x6e, 0x7e,
  117.     0x8e, 0x9e, 0xae, 0xbe, 0xce, 0xde, 0xee, 0xfe,
  118.     0x0f, 0x1f, 0x2f, 0x3f, 0x4f, 0x5f, 0x6f, 0x7f,
  119.     0x8f, 0x9f, 0xaf, 0xbf, 0xcf, 0xdf, 0xef, 0xff
  120. };
  121.  
  122. int
  123. _XReverse_Bytes (bpt, nb)
  124. register unsigned char *bpt;
  125. register int nb;
  126. {
  127.     do {
  128.         *bpt = _reverse_byte[*bpt];
  129.         bpt++;
  130.     } while (--nb > 0);
  131.     return 0;
  132. }
  133.  
  134.  
  135. /* XXX the following functions are declared int instead of void because various
  136.  * compilers and lints complain about later initialization of SwapFunc and/or
  137.  * (swapfunc == NoSwap) when void is used.
  138.  */
  139.  
  140. /*ARGSUSED*/
  141. static void
  142. NoSwap (src, dest, srclen, srcinc, destinc, height, half_order)
  143. register unsigned char *src, *dest;
  144. long srclen, srcinc, destinc;
  145. unsigned int height;
  146. int half_order;
  147. {
  148.     long h = height;
  149.  
  150.     if (srcinc == destinc)
  151.         memcpy((char *)dest, (char *)src, (int)(srcinc * (h - 1) + srclen));
  152.     else
  153.         for (; --h >= 0; src += srcinc, dest += destinc)
  154.             memcpy((char *)dest, (char *)src, (int)srclen);
  155. }
  156.  
  157. static void
  158. SwapTwoBytes (src, dest, srclen, srcinc, destinc, height, half_order)
  159. register unsigned char *src, *dest;
  160. long srclen, srcinc, destinc;
  161. unsigned int height;
  162. int half_order;
  163. {
  164.     long length = ROUNDUP(srclen, 2);
  165.     register long h, n;
  166.  
  167.     srcinc -= length;
  168.     destinc -= length;
  169.     for (h = height; --h >= 0; src += srcinc, dest += destinc) {
  170.         if ((h == 0) && (srclen != length)) {
  171.             length -= 2;
  172.             if (half_order == MSBFirst)
  173.                 *(dest + length) = *(src + length + 1);
  174.             else
  175.                 *(dest + length + 1) = *(src + length);
  176.         }
  177.         for (n = length; n > 0; n -= 2, src += 2) {
  178.             *dest++ = *(src + 1);
  179.             *dest++ = *src;
  180.         }
  181.     }
  182. }
  183.  
  184. static void
  185. SwapThreeBytes (src, dest, srclen, srcinc, destinc, height, byte_order)
  186. register unsigned char *src, *dest;
  187. long srclen, srcinc, destinc;
  188. unsigned int height;
  189. int byte_order;
  190. {
  191.     long length = ((srclen + 2) / 3) * 3;
  192.     register long h, n;
  193.  
  194.     srcinc -= length;
  195.     destinc -= length;
  196.     for (h = height; --h >= 0; src += srcinc, dest += destinc) {
  197.         if ((h == 0) && (srclen != length)) {
  198.             length -= 3;
  199.             if ((srclen - length) == 2)
  200.                 *(dest + length + 1) = *(src + length + 1);
  201.             if (byte_order == MSBFirst)
  202.                 *(dest + length) = *(src + length + 2);
  203.             else
  204.                 *(dest + length + 2) = *(src + length);
  205.         }
  206.         for (n = length; n > 0; n -= 3, src += 3) {
  207.             *dest++ = *(src + 2);
  208.             *dest++ = *(src + 1);
  209.             *dest++ = *src;
  210.         }
  211.     }
  212. }
  213.  
  214. static void
  215. SwapFourBytes (src, dest, srclen, srcinc, destinc, height, half_order)
  216. register unsigned char *src, *dest;
  217. long srclen, srcinc, destinc;
  218. unsigned int height;
  219. int half_order;
  220. {
  221.     long length = ROUNDUP(srclen, 4);
  222.     register long h, n;
  223.  
  224.     srcinc -= length;
  225.     destinc -= length;
  226.     for (h = height; --h >= 0; src += srcinc, dest += destinc) {
  227.         if ((h == 0) && (srclen != length)) {
  228.             length -= 4;
  229.             if (half_order == MSBFirst)
  230.                 *(dest + length) = *(src + length + 3);
  231.             if (((half_order == LSBFirst) && ((srclen - length) == 3)) ||
  232.                 ((half_order == MSBFirst) && (srclen & 2)))
  233.                 *(dest + length + 1) = *(src + length + 2);
  234.             if (((half_order == MSBFirst) && ((srclen - length) == 3)) ||
  235.                 ((half_order == LSBFirst) && (srclen & 2)))
  236.                 *(dest + length + 2) = *(src + length + 1);
  237.             if (half_order == LSBFirst)
  238.                 *(dest + length + 3) = *(src + length);
  239.         }
  240.         for (n = length; n > 0; n -= 4, src += 4) {
  241.             *dest++ = *(src + 3);
  242.             *dest++ = *(src + 2);
  243.             *dest++ = *(src + 1);
  244.             *dest++ = *src;
  245.         }
  246.     }
  247. }
  248.  
  249. static void
  250. SwapWords (src, dest, srclen, srcinc, destinc, height, half_order)
  251. register unsigned char *src, *dest;
  252. long srclen, srcinc, destinc;
  253. unsigned int height;
  254. int half_order;
  255. {
  256.     long length = ROUNDUP(srclen, 4);
  257.     register long h, n;
  258.  
  259.     srcinc -= length;
  260.     destinc -= length;
  261.     for (h = height; --h >= 0; src += srcinc, dest += destinc) {
  262.         if ((h == 0) && (srclen != length)) {
  263.             length -= 4;
  264.             if (half_order == MSBFirst)
  265.         *(dest + length + 1) = *(src + length + 3);
  266.             if (((half_order == LSBFirst) && ((srclen - length) == 3)) ||
  267.                 ((half_order == MSBFirst) && (srclen & 2)))
  268.                 *(dest + length) = *(src + length + 2);
  269.             if (((half_order == MSBFirst) && ((srclen - length) == 3)) ||
  270.                 ((half_order == LSBFirst) && (srclen & 2)))
  271.                 *(dest + length + 3) = *(src + length + 1);
  272.             if (half_order == LSBFirst)
  273.                 *(dest + length + 2) = *(src + length);
  274.         }
  275.         for (n = length; n > 0; n -= 4, src += 2) {
  276.             *dest++ = *(src + 2);
  277.             *dest++ = *(src + 3);
  278.             *dest++ = *src++;
  279.             *dest++ = *src++;
  280.         }
  281.     }
  282. }
  283.  
  284. static void
  285. SwapNibbles (src, dest, srclen, srcinc, destinc, height)
  286. register unsigned char *src, *dest;
  287. long srclen, srcinc, destinc;
  288. unsigned int height;
  289. {
  290.     register long h, n;
  291.     register Const unsigned char *rev = _reverse_nibs;
  292.  
  293.     srcinc -= srclen;
  294.     destinc -= srclen;
  295.     for (h = height; --h >= 0; src += srcinc, dest += destinc)
  296.         for (n = srclen; --n >= 0; )
  297.             *dest++ = rev[*src++];
  298. }
  299.  
  300. static void
  301. ShiftNibblesLeft (src, dest, srclen, srcinc, destinc, height, nibble_order)
  302. register unsigned char *src, *dest;
  303. long srclen, srcinc, destinc;
  304. unsigned int height;
  305. int nibble_order;
  306. {
  307.     register long h, n;
  308.     register unsigned char c1, c2;
  309.  
  310.     srcinc -= srclen;
  311.     destinc -= srclen;
  312.     if (nibble_order == MSBFirst) {
  313.         for (h = height; --h >= 0; src += srcinc, dest += destinc)
  314.             for (n = srclen; --n >= 0; ) {
  315.                 c1 = *src++;
  316.                 c2 = *src;
  317.                 *dest++ = ((c1 & 0x0f) << 4) | ((c2 & (unsigned)0xf0) >> 4);
  318.             }
  319.     } else {
  320.         for (h = height; --h >= 0; src += srcinc, dest += destinc)
  321.             for (n = srclen; --n >= 0; ) {
  322.                 c1 = *src++;
  323.                 c2 = *src;
  324.                 *dest++ = ((c2 & 0x0f) << 4) | ((c1 & (unsigned)0xf0) >> 4);
  325.             }
  326.     }
  327. }
  328.  
  329. /*ARGSUSED*/
  330. static void
  331. SwapBits (src, dest, srclen, srcinc, destinc, height, half_order)
  332. register unsigned char *src, *dest;
  333. long srclen, srcinc, destinc;
  334. unsigned int height;
  335. int half_order;
  336. {
  337.     register long h, n;
  338.     register Const unsigned char *rev = _reverse_byte;
  339.  
  340.     srcinc -= srclen;
  341.     destinc -= srclen;
  342.     for (h = height; --h >= 0; src += srcinc, dest += destinc)
  343.         for (n = srclen; --n >= 0; )
  344.             *dest++ = rev[*src++];
  345. }
  346.  
  347. static void
  348. SwapBitsAndTwoBytes (src, dest, srclen, srcinc, destinc, height, half_order)
  349. register unsigned char *src, *dest;
  350. long srclen, srcinc, destinc;
  351. unsigned int height;
  352. {
  353.     long length = ROUNDUP(srclen, 2);
  354.     register long h, n;
  355.     register Const unsigned char *rev = _reverse_byte;
  356.  
  357.     srcinc -= length;
  358.     destinc -= length;
  359.     for (h = height; --h >= 0; src += srcinc, dest += destinc) {
  360.         if ((h == 0) && (srclen != length)) {
  361.             length -= 2;
  362.             if (half_order == MSBFirst)
  363.                 *(dest + length) = rev[*(src + length + 1)];
  364.             else
  365.                 *(dest + length + 1) = rev[*(src + length)];
  366.         }
  367.         for (n = length; n > 0; n -= 2, src += 2) {
  368.             *dest++ = rev[*(src + 1)];
  369.             *dest++ = rev[*src];
  370.         }
  371.     }
  372. }
  373.  
  374. static void
  375. SwapBitsAndFourBytes (src, dest, srclen, srcinc, destinc, height, half_order)
  376. register unsigned char *src, *dest;
  377. long srclen, srcinc, destinc;
  378. unsigned int height;
  379. int half_order;
  380. {
  381.     long length = ROUNDUP(srclen, 4);
  382.     register long h, n;
  383.     register Const unsigned char *rev = _reverse_byte;
  384.  
  385.     srcinc -= length;
  386.     destinc -= length;
  387.     for (h = height; --h >= 0; src += srcinc, dest += destinc) {
  388.         if ((h == 0) && (srclen != length)) {
  389.             length -= 4;
  390.             if (half_order == MSBFirst)
  391.                 *(dest + length) = rev[*(src + length + 3)];
  392.             if (((half_order == LSBFirst) && ((srclen - length) == 3)) ||
  393.                 ((half_order == MSBFirst) && (srclen & 2)))
  394.                 *(dest + length + 1) = rev[*(src + length + 2)];
  395.             if (((half_order == MSBFirst) && ((srclen - length) == 3)) ||
  396.                 ((half_order == LSBFirst) && (srclen & 2)))
  397.                 *(dest + length + 2) = rev[*(src + length + 1)];
  398.             if (half_order == LSBFirst)
  399.                 *(dest + length + 3) = rev[*(src + length)];
  400.         }
  401.         for (n = length; n > 0; n -= 4, src += 4) {
  402.             *dest++ = rev[*(src + 3)];
  403.             *dest++ = rev[*(src + 2)];
  404.             *dest++ = rev[*(src + 1)];
  405.             *dest++ = rev[*src];
  406.         }
  407.     }
  408. }
  409.  
  410. static void
  411. SwapBitsAndWords (src, dest, srclen, srcinc, destinc, height, half_order)
  412. register unsigned char *src, *dest;
  413. long srclen, srcinc, destinc;
  414. unsigned int height;
  415. int half_order;
  416. {
  417.     long length = ROUNDUP(srclen, 4);
  418.     register long h, n;
  419.     register Const unsigned char *rev = _reverse_byte;
  420.  
  421.     srcinc -= length;
  422.     destinc -= length;
  423.     for (h = height; --h >= 0; src += srcinc, dest += destinc) {
  424.         if ((h == 0) && (srclen != length)) {
  425.             length -= 4;
  426.             if (half_order == MSBFirst)
  427.                 *(dest + length + 1) = rev[*(src + length + 3)];
  428.             if (((half_order == LSBFirst) && ((srclen - length) == 3)) ||
  429.                 ((half_order == MSBFirst) && (srclen & 2)))
  430.                 *(dest + length) = rev[*(src + length + 2)];
  431.             if (((half_order == MSBFirst) && ((srclen - length) == 3)) ||
  432.                 ((half_order == LSBFirst) && (srclen & 2)))
  433.                 *(dest + length + 3) = rev[*(src + length + 1)];
  434.             if (half_order == LSBFirst)
  435.                 *(dest + length + 2) = rev[*(src + length)];
  436.         }
  437.         for (n = length; n > 0; n -= 4, src += 2) {
  438.             *dest++ = rev[*(src + 2)];
  439.             *dest++ = rev[*(src + 3)];
  440.             *dest++ = rev[*src++];
  441.             *dest++ = rev[*src++];
  442.         }
  443.     }
  444. }
  445.  
  446. /*
  447.  
  448. The following table gives the bit ordering within bytes (when accessed
  449. sequentially) for a scanline containing 32 bits, with bits numbered 0 to
  450. 31, where bit 0 should be leftmost on the display.  For a given byte
  451. labelled A-B, A is for the most significant bit of the byte, and B is
  452. for the least significant bit.
  453.  
  454. legend:
  455.     1   scanline-unit = 8
  456.     2   scanline-unit = 16
  457.     4   scanline-unit = 32
  458.     M   byte-order = MostSignificant
  459.     L   byte-order = LeastSignificant
  460.     m   bit-order = MostSignificant
  461.     l   bit-order = LeastSignificant
  462.  
  463.  
  464. format    ordering
  465.  
  466. 1Mm    00-07 08-15 16-23 24-31
  467. 2Mm    00-07 08-15 16-23 24-31
  468. 4Mm    00-07 08-15 16-23 24-31
  469. 1Ml    07-00 15-08 23-16 31-24
  470. 2Ml    15-08 07-00 31-24 23-16
  471. 4Ml    31-24 23-16 15-08 07-00
  472. 1Lm    00-07 08-15 16-23 24-31
  473. 2Lm    08-15 00-07 24-31 16-23
  474. 4Lm    24-31 16-23 08-15 00-07
  475. 1Ll    07-00 15-08 23-16 31-24
  476. 2Ll    07-00 15-08 23-16 31-24
  477. 4Ll    07-00 15-08 23-16 31-24
  478.  
  479.  
  480. The following table gives the required conversion between any two
  481. formats.  It is based strictly on the table above.  If you believe one,
  482. you should believe the other.
  483.  
  484. legend:
  485.     n   no changes
  486.     s   reverse 8-bit units within 16-bit units
  487.     l   reverse 8-bit units within 32-bit units
  488.     w   reverse 16-bit units within 32-bit units
  489.     R   reverse bits within 8-bit units
  490.     S   s+R
  491.     L   l+R
  492.     W   w+R
  493.  
  494. */
  495.  
  496. static void (* RConst (SwapFunction[12][12]))() = {
  497. #define n NoSwap,
  498. #define s SwapTwoBytes,
  499. #define l SwapFourBytes,
  500. #define w SwapWords,
  501. #define R SwapBits,
  502. #define S SwapBitsAndTwoBytes,
  503. #define L SwapBitsAndFourBytes,
  504. #define W SwapBitsAndWords,
  505.  
  506. /*         1Mm 2Mm 4Mm 1Ml 2Ml 4Ml 1Lm 2Lm 4Lm 1Ll 2Ll 4Ll   */
  507. /* 1Mm */ { n   n   n   R   S   L   n   s   l   R   R   R },
  508. /* 2Mm */ { n   n   n   R   S   L   n   s   l   R   R   R },
  509. /* 4Mm */ { n   n   n   R   S   L   n   s   l   R   R   R },
  510. /* 1Ml */ { R   R   R   n   s   l   R   S   L   n   n   n },
  511. /* 2Ml */ { S   S   S   s   n   w   S   R   W   s   s   s },
  512. /* 4Ml */ { L   L   L   l   w   n   L   W   R   l   l   l },
  513. /* 1Lm */ { n   n   n   R   S   L   n   s   l   R   R   R },
  514. /* 2Lm */ { s   s   s   S   R   W   s   n   w   S   S   S },
  515. /* 4Lm */ { l   l   l   L   W   R   l   w   n   L   L   L },
  516. /* 1Ll */ { R   R   R   n   s   l   R   S   L   n   n   n },
  517. /* 2Ll */ { R   R   R   n   s   l   R   S   L   n   n   n },
  518. /* 4Ll */ { R   R   R   n   s   l   R   S   L   n   n   n }
  519.  
  520. #undef n
  521. #undef s
  522. #undef l
  523. #undef w
  524. #undef R
  525. #undef S
  526. #undef L
  527. #undef W
  528.  
  529. };
  530.  
  531. /* Of course, the table above is a lie.  We also need to factor in the
  532.  * order of the source data to cope with swapping half of a unit at the
  533.  * end of a scanline, since we are trying to avoid de-ref'ing off the
  534.  * end of the source.
  535.  *
  536.  * Defines whether the first half of a unit has the first half of the data
  537.  */
  538. static int Const HalfOrder[12] = {
  539.     LSBFirst, /* 1Mm */
  540.     LSBFirst, /* 2Mm */
  541.     LSBFirst, /* 4Mm */
  542.     LSBFirst, /* 1Ml */
  543.     MSBFirst, /* 2Ml */
  544.     MSBFirst, /* 4Ml */
  545.     LSBFirst, /* 1Lm */
  546.     MSBFirst, /* 2Lm */
  547.     MSBFirst, /* 4Lm */
  548.     LSBFirst, /* 1Ll */
  549.     LSBFirst, /* 2Ll */
  550.     LSBFirst  /* 4Ll */
  551.     };
  552.  
  553. /* Finally, for SwapWords cases, the half order depends not just on the source
  554.  * but also on the destination scanline unit.  Use of this table changes some
  555.  * MSBFirsts to LSBFirsts that are "do not care" (because the function will be
  556.  * NoSwap or SwapBits) in addition to changing the desired ones.
  557.  */
  558.  
  559. static int Const HalfOrderWord[12] = {
  560.     MSBFirst, /* 1Mm */
  561.     MSBFirst, /* 2Mm */
  562.     MSBFirst, /* 4Mm */
  563.     MSBFirst, /* 1Ml */
  564.     MSBFirst, /* 2Ml */
  565.     LSBFirst, /* 4Ml */
  566.     MSBFirst, /* 1Lm */
  567.     MSBFirst, /* 2Lm */
  568.     LSBFirst, /* 4Lm */
  569.     MSBFirst, /* 1Ll */
  570.     MSBFirst, /* 2Ll */
  571.     MSBFirst  /* 4Ll */
  572.     };
  573.  
  574. /*
  575.  * This macro creates a value from 0 to 11 suitable for indexing
  576.  * into the table above.
  577.  */
  578. #define    ComposeIndex(bitmap_unit, bitmap_bit_order, byte_order)            \
  579.         (((bitmap_unit == 32) ? 2 : ((bitmap_unit == 16) ? 1 : 0))    \
  580.              + (((bitmap_bit_order == MSBFirst) ? 0 : 3)        \
  581.              + ((byte_order == MSBFirst) ? 0 : 6)))
  582.  
  583. char *
  584.     MakeXYImage(dpy, image, req_xoffset, req_yoffset, reqwidth, reqheight, reqformat)
  585.     register Display *dpy;
  586. register XImage *image;
  587. int req_xoffset, req_yoffset;
  588. long reqwidth;
  589. long reqheight;
  590. long reqformat;
  591. {
  592.     register int j;
  593.     long total_xoffset, bytes_per_src, bytes_per_dest, length;
  594.     long bytes_per_line, bytes_per_src_plane, bytes_per_dest_plane;
  595.     long reqleftPad, reqlength;
  596.     char *src, *dest, *buf;
  597.     char *extra = (char *)NULL;
  598.     register void (*swapfunc)();
  599.     int half_order;
  600.  
  601.     total_xoffset = image->xoffset + req_xoffset;
  602.     reqleftPad = total_xoffset & (dpy->bitmap_unit - 1);
  603.     total_xoffset = (unsigned)(total_xoffset - reqleftPad) >> 3;
  604. #if 0
  605.     /* The protocol requires left-pad of zero on all ZPixmap, even
  606.      * though the 1-bit case is identical to bitmap format.  This is a
  607.      * bug in the protocol, caused because 1-bit ZPixmap was added late
  608.      * in the game.  Hairy shifting code compensation isn't worth it,
  609.      * just use XYPixmap format instead.
  610.      */
  611.     if ((reqleftPad != 0) && (reqformat == ZPixmap))
  612.         reqformat = XYPixmap;
  613. #endif
  614.     bytes_per_dest = (unsigned long)ROUNDUP((long)reqwidth + reqleftPad,
  615.                                             dpy->bitmap_pad) >> 3;
  616.     bytes_per_dest_plane = bytes_per_dest * reqheight;
  617.     length = bytes_per_dest_plane * image->depth;
  618.     reqlength += (length + 3) >> 2;
  619.  
  620.     swapfunc = SwapFunction[ComposeIndex(image->bitmap_unit,
  621.                                          image->bitmap_bit_order,
  622.                                          image->byte_order)]
  623.         [ComposeIndex(dpy->bitmap_unit,
  624.                       dpy->bitmap_bit_order,
  625.                       dpy->byte_order)];
  626.     half_order = HalfOrder[ComposeIndex(image->bitmap_unit,
  627.                                         image->bitmap_bit_order,
  628.                                         image->byte_order)];
  629.     if (half_order == MSBFirst)
  630.         half_order = HalfOrderWord[ComposeIndex(dpy->bitmap_unit,
  631.                                                 dpy->bitmap_bit_order,
  632.                                                 dpy->byte_order)];
  633.  
  634.     src = image->data + (image->bytes_per_line * req_yoffset) + total_xoffset;
  635.  
  636.     /* when total_xoffset > 0, we have to worry about stepping off the
  637.      * end of image->data.
  638.      */
  639.     if ((swapfunc == NoSwap) &&
  640.         (image->bytes_per_line == bytes_per_dest) &&
  641.         (((total_xoffset == 0) &&
  642.           ((image->depth == 1) || (image->height == reqheight))) ||
  643.          ((image->depth == 1) &&
  644.           ((req_yoffset + reqheight) < (unsigned)image->height)))) {
  645.         char *tmp = Xmalloc((unsigned long)length);
  646.         memcpy(tmp, src, length);
  647.         return tmp;
  648.     }
  649.  
  650.     length = ROUNDUP(length, 4);
  651.     if ((buf = Xmalloc((unsigned long) (length))) == NULL)
  652.         return NULL;
  653.  
  654.     bytes_per_src = (reqwidth + reqleftPad + (unsigned)7) >> 3;
  655.     bytes_per_line = image->bytes_per_line;
  656.     bytes_per_src_plane = bytes_per_line * image->height;
  657.     total_xoffset &= (image->bitmap_unit - 1) >> 3;
  658.  
  659.     if ((total_xoffset > 0) &&
  660.         (image->byte_order != image->bitmap_bit_order)) {
  661.         char *temp;
  662.         long bytes_per_temp_plane, temp_length;
  663.  
  664.         bytes_per_line = bytes_per_src + total_xoffset;
  665.         src -= total_xoffset;
  666.         bytes_per_temp_plane = bytes_per_line * reqheight;
  667.         temp_length = ROUNDUP(bytes_per_temp_plane * image->depth, 4);
  668.         if ((extra = temp = Xmalloc((unsigned) temp_length)) == NULL)
  669.             return NULL;
  670.  
  671.         swapfunc = SwapFunction[ComposeIndex(image->bitmap_unit,
  672.                                              image->bitmap_bit_order,
  673.                                              image->byte_order)]
  674.             [ComposeIndex(image->bitmap_unit,
  675.                           dpy->byte_order,
  676.                           dpy->byte_order)];
  677.         for (dest = temp, j = image->depth;
  678.              --j >= 0;
  679.              src += bytes_per_src_plane, dest += bytes_per_temp_plane)
  680.             (*swapfunc)((unsigned char *)src, (unsigned char *)dest,
  681.                         bytes_per_line, (long)image->bytes_per_line,
  682.                         bytes_per_line, reqheight, half_order);
  683.         swapfunc = SwapFunction[ComposeIndex(image->bitmap_unit,
  684.                                              dpy->byte_order,
  685.                                              dpy->byte_order)]
  686.             [ComposeIndex(dpy->bitmap_unit,
  687.                           dpy->bitmap_bit_order,
  688.                           dpy->byte_order)];
  689.         half_order = HalfOrder[ComposeIndex(image->bitmap_unit,
  690.                                             dpy->byte_order,
  691.                                             dpy->byte_order)];
  692.         src = temp + total_xoffset;
  693.         bytes_per_src_plane = bytes_per_temp_plane;
  694.     }
  695.  
  696.     for (dest = buf, j = image->depth;
  697.          --j >= 0;
  698.          src += bytes_per_src_plane, dest += bytes_per_dest_plane)
  699.         (*swapfunc)((unsigned char *)src, (unsigned char *)dest,
  700.                     bytes_per_src, bytes_per_line,
  701.                     bytes_per_dest, reqheight, half_order);
  702.  
  703.     if (extra)
  704.         Xfree(extra);
  705.  
  706.     return buf;
  707. }
  708.  
  709. char *
  710. MakeZImage(dpy, image, req_xoffset, req_yoffset,
  711.            dest_bits_per_pixel, dest_scanline_pad, reqwidth, reqheight)
  712. register Display *dpy;
  713. register XImage *image;
  714. int req_xoffset, req_yoffset, dest_bits_per_pixel, dest_scanline_pad;
  715. long reqwidth;
  716. long reqheight;
  717. {
  718.     long bytes_per_src, bytes_per_dest, length;
  719.     unsigned char *src, *dest;
  720.     unsigned char *shifted_src = NULL;
  721.     long reqleftPad, reqlength;
  722.  
  723.     reqleftPad = 0;
  724.     bytes_per_src = ROUNDUP((long)reqwidth * image->bits_per_pixel, 8) >> 3;
  725.     bytes_per_dest = ROUNDUP((long)reqwidth * dest_bits_per_pixel,
  726.                              dest_scanline_pad) >> 3;
  727.     length = bytes_per_dest * reqheight;
  728.     reqlength += (length + 3) >> 2;
  729.  
  730.     src = (unsigned char *)image->data +
  731.         (req_yoffset * image->bytes_per_line) +
  732.         ((req_xoffset * image->bits_per_pixel) >> 3);
  733.     if ((image->bits_per_pixel == 4) && ((unsigned int) req_xoffset & 0x01)) {
  734.         if (! (shifted_src = (unsigned char *)
  735.                Xmalloc((unsigned) (reqheight * image->bytes_per_line))))
  736.             return NULL;
  737.  
  738.         ShiftNibblesLeft(src, shifted_src, bytes_per_src,
  739.                          (long) image->bytes_per_line,
  740.                          (long) image->bytes_per_line, reqheight,
  741.                          image->byte_order);
  742.         src = shifted_src;
  743.     }
  744.  
  745.     /* when req_xoffset > 0, we have to worry about stepping off the
  746.      * end of image->data.
  747.      */
  748.     if (((image->byte_order == dpy->byte_order) ||
  749.          (image->bits_per_pixel == 8)) &&
  750.         ((long)image->bytes_per_line == bytes_per_dest) &&
  751.         ((req_xoffset == 0) ||
  752.          ((req_yoffset + reqheight) < (unsigned)image->height))) {
  753.         char *tmp = Xmalloc((unsigned long)length);
  754.         memcpy(tmp, src, length);
  755.  
  756.         if (shifted_src)
  757.             Xfree((char *)shifted_src);
  758.  
  759.         return tmp;
  760.     }
  761.  
  762.     if ((dest = (unsigned char *)
  763.          Xmalloc((unsigned long)(length))) == NULL) {
  764.         if (shifted_src)
  765.             Xfree((char *) shifted_src);
  766.         return NULL;
  767.     }
  768.  
  769.     if ((image->byte_order == dpy->byte_order) ||
  770.         (image->bits_per_pixel == 8))
  771.         NoSwap(src, dest, bytes_per_src, (long)image->bytes_per_line,
  772.                bytes_per_dest, reqheight, image->byte_order);
  773.     else if (image->bits_per_pixel == 32)
  774.         SwapFourBytes(src, dest, bytes_per_src, (long)image->bytes_per_line,
  775.                       bytes_per_dest, reqheight, image->byte_order);
  776.     else if (image->bits_per_pixel == 24)
  777.         SwapThreeBytes(src, dest, bytes_per_src, (long)image->bytes_per_line,
  778.                        bytes_per_dest, reqheight, image->byte_order);
  779.     else if (image->bits_per_pixel == 16)
  780.         SwapTwoBytes(src, dest, bytes_per_src, (long)image->bytes_per_line,
  781.                      bytes_per_dest, reqheight, image->byte_order);
  782.     else
  783.         SwapNibbles(src, dest, bytes_per_src, (long)image->bytes_per_line,
  784.                     bytes_per_dest, reqheight);
  785.  
  786.     if (shifted_src)
  787.         Xfree((char *)shifted_src);
  788.  
  789.     return dest;
  790. }
  791.  
  792. char *flipimage(XImage *image, char *data)
  793. {
  794.     char *temp = Xmalloc(image->bytes_per_line * image->height);
  795.     int z;
  796.  
  797.     for(z=0;z<image->height;z++)
  798.     {
  799.         memcpy(&temp[z*image->bytes_per_line], &data[(image->height-z-1)*image->bytes_per_line], image->bytes_per_line);
  800.     }
  801.     Xfree(data);
  802.     return temp;
  803. }
  804.  
  805. int XPutImage (dpy, d, gc, image, req_xoffset, req_yoffset, x, y, req_width,
  806.                req_height)
  807. register Display *dpy;
  808. Drawable d;
  809. GC gc;
  810. register XImage *image;
  811. int x, y;
  812. unsigned int req_width, req_height;
  813. int req_xoffset, req_yoffset;
  814. {
  815.     DBUG_ENTER("XPutImage")
  816.         HPS hps;
  817.     char *temp;
  818.     long format = image->format;
  819.     POINTL aptlPoints[4];
  820.     int viewheight = GetDrawableHeight(d, gc, &hps, GC_NOPATH);
  821.     BITMAPINFO2 pbmi = {
  822.         32, image->width, image->height,
  823.         1, image->bits_per_pixel, BCA_UNCOMP, image->height * image->bytes_per_line,96,96,image->depth,image->depth};
  824.         extern HAB pmctls_hab;
  825.  
  826.         if (!viewheight) DBUG_RETURN(False);
  827.  
  828.         if(image->format == XYBitmap)
  829.         {
  830.             int size = image->bytes_per_line * image->height;
  831.  
  832.             temp = Xmalloc(size);
  833.             memcpy(temp, image->data, size);
  834.             _XReverse_Bytes(temp, size);
  835.         }
  836.         else if ((image->bits_per_pixel == 1) || (image->format != ZPixmap))
  837.             temp = MakeXYImage(dpy, image, req_xoffset, req_yoffset, req_width, req_height, format);
  838.         else
  839.             temp = MakeZImage(dpy, image, req_xoffset, req_yoffset,
  840.                               dpy->pixmap_format->bits_per_pixel, dpy->pixmap_format->scanline_pad, req_width, req_height);
  841.         if(!temp)
  842.             DBUG_RETURN(TRUE);
  843.  
  844.         aptlPoints[1].x = req_width + (aptlPoints[0].x = x);
  845.         aptlPoints[0].y = (aptlPoints[1].y = viewheight - y) - req_height;
  846.         aptlPoints[3].x = req_width + (aptlPoints[2].x = req_xoffset);
  847.         aptlPoints[2].y = 0; aptlPoints[3].y = req_height;
  848.  
  849.         aptlPoints[3].x++;
  850.         aptlPoints[3].y++;
  851.  
  852.         temp = flipimage(image, temp);
  853.  
  854.         if(GpiDrawBits(hps, temp, &pbmi,(LONG)4L, aptlPoints, (image->bits_per_pixel != 1) ? ROP_SRCCOPY : ROP_NOTSRCCOPY, BBO_IGNORE)==GPI_ERROR)
  855.             printf("GpiDrawBits failed! %x\r\n", ERRORIDERROR(WinGetLastError(pmctls_hab)));
  856.  
  857.         XFree(temp);
  858.  
  859.         DBUG_RETURN(0);
  860. }
  861.  
  862.