Blame src/PutImage.c

Packit 5bd3a9
/*
Packit 5bd3a9
Packit 5bd3a9
Copyright 1986, 1998  The Open Group
Packit 5bd3a9
Packit 5bd3a9
Permission to use, copy, modify, distribute, and sell this software and its
Packit 5bd3a9
documentation for any purpose is hereby granted without fee, provided that
Packit 5bd3a9
the above copyright notice appear in all copies and that both that
Packit 5bd3a9
copyright notice and this permission notice appear in supporting
Packit 5bd3a9
documentation.
Packit 5bd3a9
Packit 5bd3a9
The above copyright notice and this permission notice shall be included in
Packit 5bd3a9
all copies or substantial portions of the Software.
Packit 5bd3a9
Packit 5bd3a9
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
Packit 5bd3a9
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
Packit 5bd3a9
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
Packit 5bd3a9
OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
Packit 5bd3a9
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
Packit 5bd3a9
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Packit 5bd3a9
Packit 5bd3a9
Except as contained in this notice, the name of The Open Group shall not be
Packit 5bd3a9
used in advertising or otherwise to promote the sale, use or other dealings
Packit 5bd3a9
in this Software without prior written authorization from The Open Group.
Packit 5bd3a9
Packit 5bd3a9
*/
Packit 5bd3a9
Packit 5bd3a9
#ifdef HAVE_CONFIG_H
Packit 5bd3a9
#include <config.h>
Packit 5bd3a9
#endif
Packit 5bd3a9
#include "Xlibint.h"
Packit 5bd3a9
#include "Xutil.h"
Packit 5bd3a9
#include <stdio.h>
Packit 5bd3a9
#include "Cr.h"
Packit 5bd3a9
#include "ImUtil.h"
Packit 5bd3a9
#include "reallocarray.h"
Packit 5bd3a9
Packit 5bd3a9
#if defined(__STDC__) && ((defined(sun) && defined(SVR4)) || defined(WIN32))
Packit 5bd3a9
#define RConst /**/
Packit 5bd3a9
#else
Packit 5bd3a9
#define RConst const
Packit 5bd3a9
#endif
Packit 5bd3a9
Packit 5bd3a9
#if defined(Lynx) && defined(ROUNDUP)
Packit 5bd3a9
#undef ROUNDUP
Packit 5bd3a9
#endif
Packit 5bd3a9
Packit 5bd3a9
/* assumes pad is a power of 2 */
Packit 5bd3a9
#define ROUNDUP(nbytes, pad) (((nbytes) + ((pad) - 1)) & ~(long)((pad) - 1))
Packit 5bd3a9
Packit 5bd3a9
static unsigned char const _reverse_byte[0x100] = {
Packit 5bd3a9
	0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
Packit 5bd3a9
	0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
Packit 5bd3a9
	0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
Packit 5bd3a9
	0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
Packit 5bd3a9
	0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
Packit 5bd3a9
	0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
Packit 5bd3a9
	0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
Packit 5bd3a9
	0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
Packit 5bd3a9
	0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
Packit 5bd3a9
	0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
Packit 5bd3a9
	0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
Packit 5bd3a9
	0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
Packit 5bd3a9
	0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
Packit 5bd3a9
	0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
Packit 5bd3a9
	0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
Packit 5bd3a9
	0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
Packit 5bd3a9
	0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
Packit 5bd3a9
	0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
Packit 5bd3a9
	0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
Packit 5bd3a9
	0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
Packit 5bd3a9
	0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
Packit 5bd3a9
	0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
Packit 5bd3a9
	0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
Packit 5bd3a9
	0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
Packit 5bd3a9
	0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
Packit 5bd3a9
	0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
Packit 5bd3a9
	0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
Packit 5bd3a9
	0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
Packit 5bd3a9
	0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
Packit 5bd3a9
	0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
Packit 5bd3a9
	0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
Packit 5bd3a9
	0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff
Packit 5bd3a9
};
Packit 5bd3a9
Packit 5bd3a9
static unsigned char const _reverse_nibs[0x100] = {
Packit 5bd3a9
	0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70,
Packit 5bd3a9
	0x80, 0x90, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0,
Packit 5bd3a9
	0x01, 0x11, 0x21, 0x31, 0x41, 0x51, 0x61, 0x71,
Packit 5bd3a9
	0x81, 0x91, 0xa1, 0xb1, 0xc1, 0xd1, 0xe1, 0xf1,
Packit 5bd3a9
	0x02, 0x12, 0x22, 0x32, 0x42, 0x52, 0x62, 0x72,
Packit 5bd3a9
	0x82, 0x92, 0xa2, 0xb2, 0xc2, 0xd2, 0xe2, 0xf2,
Packit 5bd3a9
	0x03, 0x13, 0x23, 0x33, 0x43, 0x53, 0x63, 0x73,
Packit 5bd3a9
	0x83, 0x93, 0xa3, 0xb3, 0xc3, 0xd3, 0xe3, 0xf3,
Packit 5bd3a9
	0x04, 0x14, 0x24, 0x34, 0x44, 0x54, 0x64, 0x74,
Packit 5bd3a9
	0x84, 0x94, 0xa4, 0xb4, 0xc4, 0xd4, 0xe4, 0xf4,
Packit 5bd3a9
	0x05, 0x15, 0x25, 0x35, 0x45, 0x55, 0x65, 0x75,
Packit 5bd3a9
	0x85, 0x95, 0xa5, 0xb5, 0xc5, 0xd5, 0xe5, 0xf5,
Packit 5bd3a9
	0x06, 0x16, 0x26, 0x36, 0x46, 0x56, 0x66, 0x76,
Packit 5bd3a9
	0x86, 0x96, 0xa6, 0xb6, 0xc6, 0xd6, 0xe6, 0xf6,
Packit 5bd3a9
	0x07, 0x17, 0x27, 0x37, 0x47, 0x57, 0x67, 0x77,
Packit 5bd3a9
	0x87, 0x97, 0xa7, 0xb7, 0xc7, 0xd7, 0xe7, 0xf7,
Packit 5bd3a9
	0x08, 0x18, 0x28, 0x38, 0x48, 0x58, 0x68, 0x78,
Packit 5bd3a9
	0x88, 0x98, 0xa8, 0xb8, 0xc8, 0xd8, 0xe8, 0xf8,
Packit 5bd3a9
	0x09, 0x19, 0x29, 0x39, 0x49, 0x59, 0x69, 0x79,
Packit 5bd3a9
	0x89, 0x99, 0xa9, 0xb9, 0xc9, 0xd9, 0xe9, 0xf9,
Packit 5bd3a9
	0x0a, 0x1a, 0x2a, 0x3a, 0x4a, 0x5a, 0x6a, 0x7a,
Packit 5bd3a9
	0x8a, 0x9a, 0xaa, 0xba, 0xca, 0xda, 0xea, 0xfa,
Packit 5bd3a9
	0x0b, 0x1b, 0x2b, 0x3b, 0x4b, 0x5b, 0x6b, 0x7b,
Packit 5bd3a9
	0x8b, 0x9b, 0xab, 0xbb, 0xcb, 0xdb, 0xeb, 0xfb,
Packit 5bd3a9
	0x0c, 0x1c, 0x2c, 0x3c, 0x4c, 0x5c, 0x6c, 0x7c,
Packit 5bd3a9
	0x8c, 0x9c, 0xac, 0xbc, 0xcc, 0xdc, 0xec, 0xfc,
Packit 5bd3a9
	0x0d, 0x1d, 0x2d, 0x3d, 0x4d, 0x5d, 0x6d, 0x7d,
Packit 5bd3a9
	0x8d, 0x9d, 0xad, 0xbd, 0xcd, 0xdd, 0xed, 0xfd,
Packit 5bd3a9
	0x0e, 0x1e, 0x2e, 0x3e, 0x4e, 0x5e, 0x6e, 0x7e,
Packit 5bd3a9
	0x8e, 0x9e, 0xae, 0xbe, 0xce, 0xde, 0xee, 0xfe,
Packit 5bd3a9
	0x0f, 0x1f, 0x2f, 0x3f, 0x4f, 0x5f, 0x6f, 0x7f,
Packit 5bd3a9
	0x8f, 0x9f, 0xaf, 0xbf, 0xcf, 0xdf, 0xef, 0xff
Packit 5bd3a9
};
Packit 5bd3a9
Packit 5bd3a9
int
Packit 5bd3a9
_XReverse_Bytes(
Packit 5bd3a9
    register unsigned char *bpt,
Packit 5bd3a9
    register int nb)
Packit 5bd3a9
{
Packit 5bd3a9
    do {
Packit 5bd3a9
	*bpt = _reverse_byte[*bpt];
Packit 5bd3a9
	bpt++;
Packit 5bd3a9
    } while (--nb > 0);
Packit 5bd3a9
    return 0;
Packit 5bd3a9
}
Packit 5bd3a9
Packit 5bd3a9
Packit 5bd3a9
/* XXX the following functions are declared int instead of void because various
Packit 5bd3a9
 * compilers and lints complain about later initialization of SwapFunc and/or
Packit 5bd3a9
 * (swapfunc == NoSwap) when void is used.
Packit 5bd3a9
 */
Packit 5bd3a9
Packit 5bd3a9
/*ARGSUSED*/
Packit 5bd3a9
static void
Packit 5bd3a9
NoSwap (
Packit 5bd3a9
    register unsigned char *src,
Packit 5bd3a9
    register unsigned char *dest,
Packit 5bd3a9
    long srclen,
Packit 5bd3a9
    long srcinc,
Packit 5bd3a9
    long destinc,
Packit 5bd3a9
    unsigned int height,
Packit 5bd3a9
    int half_order)
Packit 5bd3a9
{
Packit 5bd3a9
    long h = height;
Packit 5bd3a9
Packit 5bd3a9
    if (srcinc == destinc)
Packit 5bd3a9
	memcpy((char *)dest, (char *)src, (int)(srcinc * (h - 1) + srclen));
Packit 5bd3a9
    else
Packit 5bd3a9
	for (; --h >= 0; src += srcinc, dest += destinc)
Packit 5bd3a9
	    memcpy((char *)dest, (char *)src, (int)srclen);
Packit 5bd3a9
}
Packit 5bd3a9
Packit 5bd3a9
static void
Packit 5bd3a9
SwapTwoBytes (
Packit 5bd3a9
    register unsigned char *src,
Packit 5bd3a9
    register unsigned char *dest,
Packit 5bd3a9
    long srclen, long srcinc, long destinc,
Packit 5bd3a9
    unsigned int height,
Packit 5bd3a9
    int half_order)
Packit 5bd3a9
{
Packit 5bd3a9
    long length = ROUNDUP(srclen, 2);
Packit 5bd3a9
    register long h, n;
Packit 5bd3a9
Packit 5bd3a9
    srcinc -= length;
Packit 5bd3a9
    destinc -= length;
Packit 5bd3a9
    for (h = height; --h >= 0; src += srcinc, dest += destinc) {
Packit 5bd3a9
	if ((h == 0) && (srclen != length)) {
Packit 5bd3a9
	    length -= 2;
Packit 5bd3a9
	    if (half_order == MSBFirst)
Packit 5bd3a9
		*(dest + length) = *(src + length + 1);
Packit 5bd3a9
	    else
Packit 5bd3a9
		*(dest + length + 1) = *(src + length);
Packit 5bd3a9
	}
Packit 5bd3a9
	for (n = length; n > 0; n -= 2, src += 2) {
Packit 5bd3a9
	    *dest++ = *(src + 1);
Packit 5bd3a9
	    *dest++ = *src;
Packit 5bd3a9
	}
Packit 5bd3a9
    }
Packit 5bd3a9
}
Packit 5bd3a9
Packit 5bd3a9
static void
Packit 5bd3a9
SwapThreeBytes (
Packit 5bd3a9
    register unsigned char *src,
Packit 5bd3a9
    register unsigned char *dest,
Packit 5bd3a9
    long srclen, long srcinc, long destinc,
Packit 5bd3a9
    unsigned int height,
Packit 5bd3a9
    int byte_order)
Packit 5bd3a9
{
Packit 5bd3a9
    long length = ((srclen + 2) / 3) * 3;
Packit 5bd3a9
    register long h, n;
Packit 5bd3a9
Packit 5bd3a9
    srcinc -= length;
Packit 5bd3a9
    destinc -= length;
Packit 5bd3a9
    for (h = height; --h >= 0; src += srcinc, dest += destinc) {
Packit 5bd3a9
	if ((h == 0) && (srclen != length)) {
Packit 5bd3a9
	    length -= 3;
Packit 5bd3a9
	    if ((srclen - length) == 2)
Packit 5bd3a9
		*(dest + length + 1) = *(src + length + 1);
Packit 5bd3a9
	    if (byte_order == MSBFirst)
Packit 5bd3a9
		*(dest + length) = *(src + length + 2);
Packit 5bd3a9
	    else
Packit 5bd3a9
		*(dest + length + 2) = *(src + length);
Packit 5bd3a9
	}
Packit 5bd3a9
	for (n = length; n > 0; n -= 3, src += 3) {
Packit 5bd3a9
	    *dest++ = *(src + 2);
Packit 5bd3a9
	    *dest++ = *(src + 1);
Packit 5bd3a9
	    *dest++ = *src;
Packit 5bd3a9
	}
Packit 5bd3a9
    }
Packit 5bd3a9
}
Packit 5bd3a9
Packit 5bd3a9
static void
Packit 5bd3a9
SwapFourBytes (
Packit 5bd3a9
    register unsigned char *src,
Packit 5bd3a9
    register unsigned char *dest,
Packit 5bd3a9
    long srclen, long srcinc, long destinc,
Packit 5bd3a9
    unsigned int height,
Packit 5bd3a9
    int half_order)
Packit 5bd3a9
{
Packit 5bd3a9
    long length = ROUNDUP(srclen, 4);
Packit 5bd3a9
    register long h, n;
Packit 5bd3a9
Packit 5bd3a9
    srcinc -= length;
Packit 5bd3a9
    destinc -= length;
Packit 5bd3a9
    for (h = height; --h >= 0; src += srcinc, dest += destinc) {
Packit 5bd3a9
	if ((h == 0) && (srclen != length)) {
Packit 5bd3a9
	    length -= 4;
Packit 5bd3a9
	    if (half_order == MSBFirst)
Packit 5bd3a9
		*(dest + length) = *(src + length + 3);
Packit 5bd3a9
	    if (((half_order == LSBFirst) && ((srclen - length) == 3)) ||
Packit 5bd3a9
		((half_order == MSBFirst) && (srclen & 2)))
Packit 5bd3a9
		*(dest + length + 1) = *(src + length + 2);
Packit 5bd3a9
	    if (((half_order == MSBFirst) && ((srclen - length) == 3)) ||
Packit 5bd3a9
		((half_order == LSBFirst) && (srclen & 2)))
Packit 5bd3a9
		*(dest + length + 2) = *(src + length + 1);
Packit 5bd3a9
	    if (half_order == LSBFirst)
Packit 5bd3a9
		*(dest + length + 3) = *(src + length);
Packit 5bd3a9
	}
Packit 5bd3a9
	for (n = length; n > 0; n -= 4, src += 4) {
Packit 5bd3a9
	    *dest++ = *(src + 3);
Packit 5bd3a9
	    *dest++ = *(src + 2);
Packit 5bd3a9
	    *dest++ = *(src + 1);
Packit 5bd3a9
	    *dest++ = *src;
Packit 5bd3a9
	}
Packit 5bd3a9
    }
Packit 5bd3a9
}
Packit 5bd3a9
Packit 5bd3a9
static void
Packit 5bd3a9
SwapWords (
Packit 5bd3a9
    register unsigned char *src,
Packit 5bd3a9
    register unsigned char *dest,
Packit 5bd3a9
    long srclen, long srcinc, long destinc,
Packit 5bd3a9
    unsigned int height,
Packit 5bd3a9
    int half_order)
Packit 5bd3a9
{
Packit 5bd3a9
    long length = ROUNDUP(srclen, 4);
Packit 5bd3a9
    register long h, n;
Packit 5bd3a9
Packit 5bd3a9
    srcinc -= length;
Packit 5bd3a9
    destinc -= length;
Packit 5bd3a9
    for (h = height; --h >= 0; src += srcinc, dest += destinc) {
Packit 5bd3a9
	if ((h == 0) && (srclen != length)) {
Packit 5bd3a9
	    length -= 4;
Packit 5bd3a9
	    if (half_order == MSBFirst)
Packit 5bd3a9
		*(dest + length + 1) = *(src + length + 3);
Packit 5bd3a9
	    if (((half_order == LSBFirst) && ((srclen - length) == 3)) ||
Packit 5bd3a9
		((half_order == MSBFirst) && (srclen & 2)))
Packit 5bd3a9
		*(dest + length) = *(src + length + 2);
Packit 5bd3a9
	    if (((half_order == MSBFirst) && ((srclen - length) == 3)) ||
Packit 5bd3a9
		((half_order == LSBFirst) && (srclen & 2)))
Packit 5bd3a9
		*(dest + length + 3) = *(src + length + 1);
Packit 5bd3a9
	    if (half_order == LSBFirst)
Packit 5bd3a9
		*(dest + length + 2) = *(src + length);
Packit 5bd3a9
	}
Packit 5bd3a9
	for (n = length; n > 0; n -= 4, src += 2) {
Packit 5bd3a9
	    *dest++ = *(src + 2);
Packit 5bd3a9
	    *dest++ = *(src + 3);
Packit 5bd3a9
	    *dest++ = *src++;
Packit 5bd3a9
	    *dest++ = *src++;
Packit 5bd3a9
	}
Packit 5bd3a9
    }
Packit 5bd3a9
}
Packit 5bd3a9
Packit 5bd3a9
static void
Packit 5bd3a9
SwapNibbles(
Packit 5bd3a9
    register unsigned char *src,
Packit 5bd3a9
    register unsigned char *dest,
Packit 5bd3a9
    long srclen, long srcinc, long destinc,
Packit 5bd3a9
    unsigned int height)
Packit 5bd3a9
{
Packit 5bd3a9
    register long h, n;
Packit 5bd3a9
    register const unsigned char *rev = _reverse_nibs;
Packit 5bd3a9
Packit 5bd3a9
    srcinc -= srclen;
Packit 5bd3a9
    destinc -= srclen;
Packit 5bd3a9
    for (h = height; --h >= 0; src += srcinc, dest += destinc)
Packit 5bd3a9
	for (n = srclen; --n >= 0; )
Packit 5bd3a9
	    *dest++ = rev[*src++];
Packit 5bd3a9
}
Packit 5bd3a9
Packit 5bd3a9
static void
Packit 5bd3a9
ShiftNibblesLeft (
Packit 5bd3a9
    register unsigned char *src,
Packit 5bd3a9
    register unsigned char *dest,
Packit 5bd3a9
    long srclen, long srcinc, long destinc,
Packit 5bd3a9
    unsigned int height,
Packit 5bd3a9
    int nibble_order)
Packit 5bd3a9
{
Packit 5bd3a9
    register long h, n;
Packit 5bd3a9
    register unsigned char c1, c2;
Packit 5bd3a9
Packit 5bd3a9
    srcinc -= srclen;
Packit 5bd3a9
    destinc -= srclen;
Packit 5bd3a9
    if (nibble_order == MSBFirst) {
Packit 5bd3a9
	for (h = height; --h >= 0; src += srcinc, dest += destinc)
Packit 5bd3a9
	    for (n = srclen; --n >= 0; ) {
Packit 5bd3a9
		c1 = *src++;
Packit 5bd3a9
		c2 = *src;
Packit 5bd3a9
		*dest++ = ((c1 & 0x0f) << 4) | ((c2 & (unsigned)0xf0) >> 4);
Packit 5bd3a9
	    }
Packit 5bd3a9
    } else {
Packit 5bd3a9
	for (h = height; --h >= 0; src += srcinc, dest += destinc)
Packit 5bd3a9
	    for (n = srclen; --n >= 0; ) {
Packit 5bd3a9
		c1 = *src++;
Packit 5bd3a9
		c2 = *src;
Packit 5bd3a9
		*dest++ = ((c2 & 0x0f) << 4) | ((c1 & (unsigned)0xf0) >> 4);
Packit 5bd3a9
	    }
Packit 5bd3a9
    }
Packit 5bd3a9
}
Packit 5bd3a9
Packit 5bd3a9
/*ARGSUSED*/
Packit 5bd3a9
static void
Packit 5bd3a9
SwapBits(
Packit 5bd3a9
    register unsigned char *src,
Packit 5bd3a9
    register unsigned char *dest,
Packit 5bd3a9
    long srclen, long srcinc, long destinc,
Packit 5bd3a9
    unsigned int height,
Packit 5bd3a9
    int half_order)
Packit 5bd3a9
{
Packit 5bd3a9
    register long h, n;
Packit 5bd3a9
    register const unsigned char *rev = _reverse_byte;
Packit 5bd3a9
Packit 5bd3a9
    srcinc -= srclen;
Packit 5bd3a9
    destinc -= srclen;
Packit 5bd3a9
    for (h = height; --h >= 0; src += srcinc, dest += destinc)
Packit 5bd3a9
	for (n = srclen; --n >= 0; )
Packit 5bd3a9
	    *dest++ = rev[*src++];
Packit 5bd3a9
}
Packit 5bd3a9
Packit 5bd3a9
static void
Packit 5bd3a9
SwapBitsAndTwoBytes(
Packit 5bd3a9
    register unsigned char *src,
Packit 5bd3a9
    register unsigned char *dest,
Packit 5bd3a9
    long srclen, long srcinc, long destinc,
Packit 5bd3a9
    unsigned int height,
Packit 5bd3a9
    int half_order)
Packit 5bd3a9
{
Packit 5bd3a9
    long length = ROUNDUP(srclen, 2);
Packit 5bd3a9
    register long h, n;
Packit 5bd3a9
    register const unsigned char *rev = _reverse_byte;
Packit 5bd3a9
Packit 5bd3a9
    srcinc -= length;
Packit 5bd3a9
    destinc -= length;
Packit 5bd3a9
    for (h = height; --h >= 0; src += srcinc, dest += destinc) {
Packit 5bd3a9
	if ((h == 0) && (srclen != length)) {
Packit 5bd3a9
	    length -= 2;
Packit 5bd3a9
	    if (half_order == MSBFirst)
Packit 5bd3a9
		*(dest + length) = rev[*(src + length + 1)];
Packit 5bd3a9
	    else
Packit 5bd3a9
		*(dest + length + 1) = rev[*(src + length)];
Packit 5bd3a9
	}
Packit 5bd3a9
	for (n = length; n > 0; n -= 2, src += 2) {
Packit 5bd3a9
	    *dest++ = rev[*(src + 1)];
Packit 5bd3a9
	    *dest++ = rev[*src];
Packit 5bd3a9
	}
Packit 5bd3a9
    }
Packit 5bd3a9
}
Packit 5bd3a9
Packit 5bd3a9
static void
Packit 5bd3a9
SwapBitsAndFourBytes(
Packit 5bd3a9
    register unsigned char *src,
Packit 5bd3a9
    register unsigned char *dest,
Packit 5bd3a9
    long srclen, long srcinc, long destinc,
Packit 5bd3a9
    unsigned int height,
Packit 5bd3a9
    int half_order)
Packit 5bd3a9
{
Packit 5bd3a9
    long length = ROUNDUP(srclen, 4);
Packit 5bd3a9
    register long h, n;
Packit 5bd3a9
    register const unsigned char *rev = _reverse_byte;
Packit 5bd3a9
Packit 5bd3a9
    srcinc -= length;
Packit 5bd3a9
    destinc -= length;
Packit 5bd3a9
    for (h = height; --h >= 0; src += srcinc, dest += destinc) {
Packit 5bd3a9
	if ((h == 0) && (srclen != length)) {
Packit 5bd3a9
	    length -= 4;
Packit 5bd3a9
	    if (half_order == MSBFirst)
Packit 5bd3a9
		*(dest + length) = rev[*(src + length + 3)];
Packit 5bd3a9
	    if (((half_order == LSBFirst) && ((srclen - length) == 3)) ||
Packit 5bd3a9
		((half_order == MSBFirst) && (srclen & 2)))
Packit 5bd3a9
		*(dest + length + 1) = rev[*(src + length + 2)];
Packit 5bd3a9
	    if (((half_order == MSBFirst) && ((srclen - length) == 3)) ||
Packit 5bd3a9
		((half_order == LSBFirst) && (srclen & 2)))
Packit 5bd3a9
		*(dest + length + 2) = rev[*(src + length + 1)];
Packit 5bd3a9
	    if (half_order == LSBFirst)
Packit 5bd3a9
		*(dest + length + 3) = rev[*(src + length)];
Packit 5bd3a9
	}
Packit 5bd3a9
	for (n = length; n > 0; n -= 4, src += 4) {
Packit 5bd3a9
	    *dest++ = rev[*(src + 3)];
Packit 5bd3a9
	    *dest++ = rev[*(src + 2)];
Packit 5bd3a9
	    *dest++ = rev[*(src + 1)];
Packit 5bd3a9
	    *dest++ = rev[*src];
Packit 5bd3a9
	}
Packit 5bd3a9
    }
Packit 5bd3a9
}
Packit 5bd3a9
Packit 5bd3a9
static void
Packit 5bd3a9
SwapBitsAndWords(
Packit 5bd3a9
    register unsigned char *src,
Packit 5bd3a9
    register unsigned char *dest,
Packit 5bd3a9
    long srclen, long srcinc, long destinc,
Packit 5bd3a9
    unsigned int height,
Packit 5bd3a9
    int half_order)
Packit 5bd3a9
{
Packit 5bd3a9
    long length = ROUNDUP(srclen, 4);
Packit 5bd3a9
    register long h, n;
Packit 5bd3a9
    register const unsigned char *rev = _reverse_byte;
Packit 5bd3a9
Packit 5bd3a9
    srcinc -= length;
Packit 5bd3a9
    destinc -= length;
Packit 5bd3a9
    for (h = height; --h >= 0; src += srcinc, dest += destinc) {
Packit 5bd3a9
	if ((h == 0) && (srclen != length)) {
Packit 5bd3a9
	    length -= 4;
Packit 5bd3a9
	    if (half_order == MSBFirst)
Packit 5bd3a9
		*(dest + length + 1) = rev[*(src + length + 3)];
Packit 5bd3a9
	    if (((half_order == LSBFirst) && ((srclen - length) == 3)) ||
Packit 5bd3a9
		((half_order == MSBFirst) && (srclen & 2)))
Packit 5bd3a9
		*(dest + length) = rev[*(src + length + 2)];
Packit 5bd3a9
	    if (((half_order == MSBFirst) && ((srclen - length) == 3)) ||
Packit 5bd3a9
		((half_order == LSBFirst) && (srclen & 2)))
Packit 5bd3a9
		*(dest + length + 3) = rev[*(src + length + 1)];
Packit 5bd3a9
	    if (half_order == LSBFirst)
Packit 5bd3a9
		*(dest + length + 2) = rev[*(src + length)];
Packit 5bd3a9
	}
Packit 5bd3a9
	for (n = length; n > 0; n -= 4, src += 2) {
Packit 5bd3a9
	    *dest++ = rev[*(src + 2)];
Packit 5bd3a9
	    *dest++ = rev[*(src + 3)];
Packit 5bd3a9
	    *dest++ = rev[*src++];
Packit 5bd3a9
	    *dest++ = rev[*src++];
Packit 5bd3a9
	}
Packit 5bd3a9
    }
Packit 5bd3a9
}
Packit 5bd3a9
Packit 5bd3a9
/*
Packit 5bd3a9
Packit 5bd3a9
The following table gives the bit ordering within bytes (when accessed
Packit 5bd3a9
sequentially) for a scanline containing 32 bits, with bits numbered 0 to
Packit 5bd3a9
31, where bit 0 should be leftmost on the display.  For a given byte
Packit 5bd3a9
labelled A-B, A is for the most significant bit of the byte, and B is
Packit 5bd3a9
for the least significant bit.
Packit 5bd3a9
Packit 5bd3a9
legend:
Packit 5bd3a9
	1   scanline-unit = 8
Packit 5bd3a9
	2   scanline-unit = 16
Packit 5bd3a9
	4   scanline-unit = 32
Packit 5bd3a9
	M   byte-order = MostSignificant
Packit 5bd3a9
	L   byte-order = LeastSignificant
Packit 5bd3a9
	m   bit-order = MostSignificant
Packit 5bd3a9
	l   bit-order = LeastSignificant
Packit 5bd3a9
Packit 5bd3a9
Packit 5bd3a9
format	ordering
Packit 5bd3a9
Packit 5bd3a9
1Mm	00-07 08-15 16-23 24-31
Packit 5bd3a9
2Mm	00-07 08-15 16-23 24-31
Packit 5bd3a9
4Mm	00-07 08-15 16-23 24-31
Packit 5bd3a9
1Ml	07-00 15-08 23-16 31-24
Packit 5bd3a9
2Ml	15-08 07-00 31-24 23-16
Packit 5bd3a9
4Ml	31-24 23-16 15-08 07-00
Packit 5bd3a9
1Lm	00-07 08-15 16-23 24-31
Packit 5bd3a9
2Lm	08-15 00-07 24-31 16-23
Packit 5bd3a9
4Lm	24-31 16-23 08-15 00-07
Packit 5bd3a9
1Ll	07-00 15-08 23-16 31-24
Packit 5bd3a9
2Ll	07-00 15-08 23-16 31-24
Packit 5bd3a9
4Ll	07-00 15-08 23-16 31-24
Packit 5bd3a9
Packit 5bd3a9
Packit 5bd3a9
The following table gives the required conversion between any two
Packit 5bd3a9
formats.  It is based strictly on the table above.  If you believe one,
Packit 5bd3a9
you should believe the other.
Packit 5bd3a9
Packit 5bd3a9
legend:
Packit 5bd3a9
	n   no changes
Packit 5bd3a9
	s   reverse 8-bit units within 16-bit units
Packit 5bd3a9
	l   reverse 8-bit units within 32-bit units
Packit 5bd3a9
	w   reverse 16-bit units within 32-bit units
Packit 5bd3a9
	R   reverse bits within 8-bit units
Packit 5bd3a9
	S   s+R
Packit 5bd3a9
	L   l+R
Packit 5bd3a9
	W   w+R
Packit 5bd3a9
Packit 5bd3a9
*/
Packit 5bd3a9
Packit 5bd3a9
static void (* RConst (SwapFunction[12][12]))(
Packit 5bd3a9
    register unsigned char *src,
Packit 5bd3a9
    register unsigned char *dest,
Packit 5bd3a9
    long srclen,
Packit 5bd3a9
    long srcinc,
Packit 5bd3a9
    long destinc,
Packit 5bd3a9
    unsigned int height,
Packit 5bd3a9
    int half_order) = {
Packit 5bd3a9
#define n NoSwap,
Packit 5bd3a9
#define s SwapTwoBytes,
Packit 5bd3a9
#define l SwapFourBytes,
Packit 5bd3a9
#define w SwapWords,
Packit 5bd3a9
#define R SwapBits,
Packit 5bd3a9
#define S SwapBitsAndTwoBytes,
Packit 5bd3a9
#define L SwapBitsAndFourBytes,
Packit 5bd3a9
#define W SwapBitsAndWords,
Packit 5bd3a9
Packit 5bd3a9
/*         1Mm 2Mm 4Mm 1Ml 2Ml 4Ml 1Lm 2Lm 4Lm 1Ll 2Ll 4Ll   */
Packit 5bd3a9
/* 1Mm */ { n   n   n   R   S   L   n   s   l   R   R   R },
Packit 5bd3a9
/* 2Mm */ { n   n   n   R   S   L   n   s   l   R   R   R },
Packit 5bd3a9
/* 4Mm */ { n   n   n   R   S   L   n   s   l   R   R   R },
Packit 5bd3a9
/* 1Ml */ { R   R   R   n   s   l   R   S   L   n   n   n },
Packit 5bd3a9
/* 2Ml */ { S   S   S   s   n   w   S   R   W   s   s   s },
Packit 5bd3a9
/* 4Ml */ { L   L   L   l   w   n   L   W   R   l   l   l },
Packit 5bd3a9
/* 1Lm */ { n   n   n   R   S   L   n   s   l   R   R   R },
Packit 5bd3a9
/* 2Lm */ { s   s   s   S   R   W   s   n   w   S   S   S },
Packit 5bd3a9
/* 4Lm */ { l   l   l   L   W   R   l   w   n   L   L   L },
Packit 5bd3a9
/* 1Ll */ { R   R   R   n   s   l   R   S   L   n   n   n },
Packit 5bd3a9
/* 2Ll */ { R   R   R   n   s   l   R   S   L   n   n   n },
Packit 5bd3a9
/* 4Ll */ { R   R   R   n   s   l   R   S   L   n   n   n }
Packit 5bd3a9
Packit 5bd3a9
#undef n
Packit 5bd3a9
#undef s
Packit 5bd3a9
#undef l
Packit 5bd3a9
#undef w
Packit 5bd3a9
#undef R
Packit 5bd3a9
#undef S
Packit 5bd3a9
#undef L
Packit 5bd3a9
#undef W
Packit 5bd3a9
Packit 5bd3a9
};
Packit 5bd3a9
Packit 5bd3a9
/* Of course, the table above is a lie.  We also need to factor in the
Packit 5bd3a9
 * order of the source data to cope with swapping half of a unit at the
Packit 5bd3a9
 * end of a scanline, since we are trying to avoid de-ref'ing off the
Packit 5bd3a9
 * end of the source.
Packit 5bd3a9
 *
Packit 5bd3a9
 * Defines whether the first half of a unit has the first half of the data
Packit 5bd3a9
 */
Packit 5bd3a9
static int const HalfOrder[12] = {
Packit 5bd3a9
	LSBFirst, /* 1Mm */
Packit 5bd3a9
	LSBFirst, /* 2Mm */
Packit 5bd3a9
	LSBFirst, /* 4Mm */
Packit 5bd3a9
	LSBFirst, /* 1Ml */
Packit 5bd3a9
	MSBFirst, /* 2Ml */
Packit 5bd3a9
	MSBFirst, /* 4Ml */
Packit 5bd3a9
	LSBFirst, /* 1Lm */
Packit 5bd3a9
	MSBFirst, /* 2Lm */
Packit 5bd3a9
	MSBFirst, /* 4Lm */
Packit 5bd3a9
	LSBFirst, /* 1Ll */
Packit 5bd3a9
	LSBFirst, /* 2Ll */
Packit 5bd3a9
	LSBFirst  /* 4Ll */
Packit 5bd3a9
	};
Packit 5bd3a9
Packit 5bd3a9
/* Finally, for SwapWords cases, the half order depends not just on the source
Packit 5bd3a9
 * but also on the destination scanline unit.  Use of this table changes some
Packit 5bd3a9
 * MSBFirsts to LSBFirsts that are "do not care" (because the function will be
Packit 5bd3a9
 * NoSwap or SwapBits) in addition to changing the desired ones.
Packit 5bd3a9
 */
Packit 5bd3a9
Packit 5bd3a9
static int const HalfOrderWord[12] = {
Packit 5bd3a9
	MSBFirst, /* 1Mm */
Packit 5bd3a9
	MSBFirst, /* 2Mm */
Packit 5bd3a9
	MSBFirst, /* 4Mm */
Packit 5bd3a9
	MSBFirst, /* 1Ml */
Packit 5bd3a9
	MSBFirst, /* 2Ml */
Packit 5bd3a9
	LSBFirst, /* 4Ml */
Packit 5bd3a9
	MSBFirst, /* 1Lm */
Packit 5bd3a9
	MSBFirst, /* 2Lm */
Packit 5bd3a9
	LSBFirst, /* 4Lm */
Packit 5bd3a9
	MSBFirst, /* 1Ll */
Packit 5bd3a9
	MSBFirst, /* 2Ll */
Packit 5bd3a9
	MSBFirst  /* 4Ll */
Packit 5bd3a9
	};
Packit 5bd3a9
Packit 5bd3a9
/*
Packit 5bd3a9
 * This macro creates a value from 0 to 11 suitable for indexing
Packit 5bd3a9
 * into the table above.
Packit 5bd3a9
 */
Packit 5bd3a9
#define	ComposeIndex(bitmap_unit, bitmap_bit_order, byte_order)			\
Packit 5bd3a9
		(((bitmap_unit == 32) ? 2 : ((bitmap_unit == 16) ? 1 : 0))	\
Packit 5bd3a9
		     + (((bitmap_bit_order == MSBFirst) ? 0 : 3)		\
Packit 5bd3a9
		     + ((byte_order == MSBFirst) ? 0 : 6)))
Packit 5bd3a9
Packit 5bd3a9
/* Cancel a GetReq operation, before doing _XSend or Data */
Packit 5bd3a9
Packit 5bd3a9
#define UnGetReq(name)\
Packit 5bd3a9
    dpy->bufptr -= SIZEOF(x##name##Req);\
Packit 5bd3a9
    X_DPY_REQUEST_DECREMENT(dpy)
Packit 5bd3a9
Packit 5bd3a9
static void
Packit 5bd3a9
SendXYImage(
Packit 5bd3a9
    register Display *dpy,
Packit 5bd3a9
    register xPutImageReq *req,
Packit 5bd3a9
    register XImage *image,
Packit 5bd3a9
    int req_xoffset, int req_yoffset)
Packit 5bd3a9
{
Packit 5bd3a9
    register int j;
Packit 5bd3a9
    long total_xoffset, bytes_per_src, bytes_per_dest, length;
Packit 5bd3a9
    long bytes_per_line, bytes_per_src_plane, bytes_per_dest_plane;
Packit 5bd3a9
    char *src, *dest, *buf;
Packit 5bd3a9
    char *extra = (char *)NULL;
Packit 5bd3a9
    register void (*swapfunc)(
Packit 5bd3a9
        register unsigned char *src,
Packit 5bd3a9
        register unsigned char *dest,
Packit 5bd3a9
        long srclen,
Packit 5bd3a9
        long srcinc,
Packit 5bd3a9
        long destinc,
Packit 5bd3a9
        unsigned int height,
Packit 5bd3a9
        int half_order);
Packit 5bd3a9
    int half_order;
Packit 5bd3a9
Packit 5bd3a9
    total_xoffset = image->xoffset + req_xoffset;
Packit 5bd3a9
    req->leftPad = total_xoffset & (dpy->bitmap_unit - 1);
Packit 5bd3a9
    total_xoffset = (unsigned)(total_xoffset - req->leftPad) >> 3;
Packit 5bd3a9
    /* The protocol requires left-pad of zero on all ZPixmap, even
Packit 5bd3a9
     * though the 1-bit case is identical to bitmap format.  This is a
Packit 5bd3a9
     * bug in the protocol, caused because 1-bit ZPixmap was added late
Packit 5bd3a9
     * in the game.  Hairy shifting code compensation isn't worth it,
Packit 5bd3a9
     * just use XYPixmap format instead.
Packit 5bd3a9
     */
Packit 5bd3a9
    if ((req->leftPad != 0) && (req->format == ZPixmap))
Packit 5bd3a9
	req->format = XYPixmap;
Packit 5bd3a9
    bytes_per_dest = (unsigned long)ROUNDUP((long)req->width + req->leftPad,
Packit 5bd3a9
					    dpy->bitmap_pad) >> 3;
Packit 5bd3a9
    bytes_per_dest_plane = bytes_per_dest * req->height;
Packit 5bd3a9
    length = bytes_per_dest_plane * image->depth;
Packit 5bd3a9
    req->length += (length + 3) >> 2;
Packit 5bd3a9
Packit 5bd3a9
    swapfunc = SwapFunction[ComposeIndex(image->bitmap_unit,
Packit 5bd3a9
					 image->bitmap_bit_order,
Packit 5bd3a9
					 image->byte_order)]
Packit 5bd3a9
			   [ComposeIndex(dpy->bitmap_unit,
Packit 5bd3a9
					 dpy->bitmap_bit_order,
Packit 5bd3a9
					 dpy->byte_order)];
Packit 5bd3a9
    half_order = HalfOrder[ComposeIndex(image->bitmap_unit,
Packit 5bd3a9
					image->bitmap_bit_order,
Packit 5bd3a9
					image->byte_order)];
Packit 5bd3a9
    if (half_order == MSBFirst)
Packit 5bd3a9
	half_order = HalfOrderWord[ComposeIndex(dpy->bitmap_unit,
Packit 5bd3a9
						dpy->bitmap_bit_order,
Packit 5bd3a9
						dpy->byte_order)];
Packit 5bd3a9
Packit 5bd3a9
    src = image->data + (image->bytes_per_line * req_yoffset) + total_xoffset;
Packit 5bd3a9
Packit 5bd3a9
    /* when total_xoffset > 0, we have to worry about stepping off the
Packit 5bd3a9
     * end of image->data.
Packit 5bd3a9
     */
Packit 5bd3a9
    if ((swapfunc == NoSwap) &&
Packit 5bd3a9
	(image->bytes_per_line == bytes_per_dest) &&
Packit 5bd3a9
	(((total_xoffset == 0) &&
Packit 5bd3a9
	  ((image->depth == 1) || (image->height == req->height))) ||
Packit 5bd3a9
	 ((image->depth == 1) &&
Packit 5bd3a9
	  ((req_yoffset + req->height) < (unsigned)image->height)))) {
Packit 5bd3a9
	Data(dpy, src, length);
Packit 5bd3a9
	return;
Packit 5bd3a9
    }
Packit 5bd3a9
Packit 5bd3a9
    length = ROUNDUP(length, 4);
Packit 5bd3a9
    if ((dpy->bufptr + length) > dpy->bufmax) {
Packit 5bd3a9
	if ((buf = _XAllocScratch(dpy, length)) == NULL) {
Packit 5bd3a9
	    UnGetReq(PutImage);
Packit 5bd3a9
	    return;
Packit 5bd3a9
	}
Packit 5bd3a9
    }
Packit 5bd3a9
    else
Packit 5bd3a9
	buf = dpy->bufptr;
Packit 5bd3a9
Packit 5bd3a9
    bytes_per_src = (req->width + req->leftPad + (unsigned)7) >> 3;
Packit 5bd3a9
    bytes_per_line = image->bytes_per_line;
Packit 5bd3a9
    bytes_per_src_plane = bytes_per_line * image->height;
Packit 5bd3a9
    total_xoffset &= (image->bitmap_unit - 1) >> 3;
Packit 5bd3a9
Packit 5bd3a9
    if ((total_xoffset > 0) &&
Packit 5bd3a9
	(image->byte_order != image->bitmap_bit_order)) {
Packit 5bd3a9
	char *temp;
Packit 5bd3a9
	long bytes_per_temp_plane, temp_length;
Packit 5bd3a9
Packit 5bd3a9
	bytes_per_line = bytes_per_src + total_xoffset;
Packit 5bd3a9
	src -= total_xoffset;
Packit 5bd3a9
	bytes_per_temp_plane = bytes_per_line * req->height;
Packit 5bd3a9
	temp_length = ROUNDUP(bytes_per_temp_plane * image->depth, 4);
Packit 5bd3a9
	if (buf == dpy->bufptr) {
Packit 5bd3a9
	    if (! (temp = _XAllocScratch(dpy, temp_length))) {
Packit 5bd3a9
		UnGetReq(PutImage);
Packit 5bd3a9
		return;
Packit 5bd3a9
	    }
Packit 5bd3a9
	}
Packit 5bd3a9
	else
Packit 5bd3a9
	    if ((extra = temp = Xmalloc(temp_length)) == NULL) {
Packit 5bd3a9
		UnGetReq(PutImage);
Packit 5bd3a9
		return;
Packit 5bd3a9
	    }
Packit 5bd3a9
Packit 5bd3a9
	swapfunc = SwapFunction[ComposeIndex(image->bitmap_unit,
Packit 5bd3a9
					     image->bitmap_bit_order,
Packit 5bd3a9
					     image->byte_order)]
Packit 5bd3a9
			       [ComposeIndex(image->bitmap_unit,
Packit 5bd3a9
					     dpy->byte_order,
Packit 5bd3a9
					     dpy->byte_order)];
Packit 5bd3a9
	for (dest = temp, j = image->depth;
Packit 5bd3a9
	     --j >= 0;
Packit 5bd3a9
	     src += bytes_per_src_plane, dest += bytes_per_temp_plane)
Packit 5bd3a9
	    (*swapfunc)((unsigned char *)src, (unsigned char *)dest,
Packit 5bd3a9
			bytes_per_line, (long)image->bytes_per_line,
Packit 5bd3a9
			bytes_per_line, req->height, half_order);
Packit 5bd3a9
	swapfunc = SwapFunction[ComposeIndex(image->bitmap_unit,
Packit 5bd3a9
					     dpy->byte_order,
Packit 5bd3a9
					     dpy->byte_order)]
Packit 5bd3a9
			       [ComposeIndex(dpy->bitmap_unit,
Packit 5bd3a9
					     dpy->bitmap_bit_order,
Packit 5bd3a9
					     dpy->byte_order)];
Packit 5bd3a9
	half_order = HalfOrder[ComposeIndex(image->bitmap_unit,
Packit 5bd3a9
					    dpy->byte_order,
Packit 5bd3a9
					    dpy->byte_order)];
Packit 5bd3a9
	src = temp + total_xoffset;
Packit 5bd3a9
	bytes_per_src_plane = bytes_per_temp_plane;
Packit 5bd3a9
    }
Packit 5bd3a9
Packit 5bd3a9
    for (dest = buf, j = image->depth;
Packit 5bd3a9
	 --j >= 0;
Packit 5bd3a9
	 src += bytes_per_src_plane, dest += bytes_per_dest_plane)
Packit 5bd3a9
	(*swapfunc)((unsigned char *)src, (unsigned char *)dest,
Packit 5bd3a9
		    bytes_per_src, bytes_per_line,
Packit 5bd3a9
		    bytes_per_dest, req->height, half_order);
Packit 5bd3a9
Packit 5bd3a9
    Xfree(extra);
Packit 5bd3a9
Packit 5bd3a9
    if (buf == dpy->bufptr)
Packit 5bd3a9
	dpy->bufptr += length;
Packit 5bd3a9
    else
Packit 5bd3a9
	_XSend(dpy, buf, length);
Packit 5bd3a9
  }
Packit 5bd3a9
Packit 5bd3a9
static void
Packit 5bd3a9
SendZImage(
Packit 5bd3a9
    register Display *dpy,
Packit 5bd3a9
    register xPutImageReq *req,
Packit 5bd3a9
    register XImage *image,
Packit 5bd3a9
    int req_xoffset, int req_yoffset,
Packit 5bd3a9
    int dest_bits_per_pixel, int dest_scanline_pad)
Packit 5bd3a9
{
Packit 5bd3a9
    long bytes_per_src, bytes_per_dest, length;
Packit 5bd3a9
    unsigned char *src, *dest;
Packit 5bd3a9
    unsigned char *shifted_src = NULL;
Packit 5bd3a9
Packit 5bd3a9
    req->leftPad = 0;
Packit 5bd3a9
    bytes_per_src = ROUNDUP((long)req->width * image->bits_per_pixel, 8) >> 3;
Packit 5bd3a9
    bytes_per_dest = ROUNDUP((long)req->width * dest_bits_per_pixel,
Packit 5bd3a9
			     dest_scanline_pad) >> 3;
Packit 5bd3a9
    length = bytes_per_dest * req->height;
Packit 5bd3a9
    req->length += (length + 3) >> 2;
Packit 5bd3a9
Packit 5bd3a9
    src = (unsigned char *)image->data +
Packit 5bd3a9
	  (req_yoffset * image->bytes_per_line) +
Packit 5bd3a9
	  ((req_xoffset * image->bits_per_pixel) >> 3);
Packit 5bd3a9
    if ((image->bits_per_pixel == 4) && ((unsigned int) req_xoffset & 0x01)) {
Packit 5bd3a9
	if (! (shifted_src = Xmallocarray(req->height, image->bytes_per_line))) {
Packit 5bd3a9
	    UnGetReq(PutImage);
Packit 5bd3a9
	    return;
Packit 5bd3a9
	}
Packit 5bd3a9
Packit 5bd3a9
	ShiftNibblesLeft(src, shifted_src, bytes_per_src,
Packit 5bd3a9
			 (long) image->bytes_per_line,
Packit 5bd3a9
			 (long) image->bytes_per_line, req->height,
Packit 5bd3a9
			 image->byte_order);
Packit 5bd3a9
	src = shifted_src;
Packit 5bd3a9
    }
Packit 5bd3a9
Packit 5bd3a9
    /* when req_xoffset > 0, we have to worry about stepping off the
Packit 5bd3a9
     * end of image->data.
Packit 5bd3a9
     */
Packit 5bd3a9
    if (((image->byte_order == dpy->byte_order) ||
Packit 5bd3a9
	 (image->bits_per_pixel == 8)) &&
Packit 5bd3a9
	((long)image->bytes_per_line == bytes_per_dest) &&
Packit 5bd3a9
	((req_xoffset == 0) ||
Packit 5bd3a9
	 ((req_yoffset + req->height) < (unsigned)image->height))) {
Packit 5bd3a9
	Data(dpy, (char *)src, length);
Packit 5bd3a9
	Xfree(shifted_src);
Packit 5bd3a9
	return;
Packit 5bd3a9
    }
Packit 5bd3a9
Packit 5bd3a9
    length = ROUNDUP(length, 4);
Packit 5bd3a9
    if ((dpy->bufptr + length) <= dpy->bufmax)
Packit 5bd3a9
	dest = (unsigned char *)dpy->bufptr;
Packit 5bd3a9
    else
Packit 5bd3a9
	if ((dest = (unsigned char *)
Packit 5bd3a9
	     _XAllocScratch(dpy, length)) == NULL) {
Packit 5bd3a9
	    Xfree(shifted_src);
Packit 5bd3a9
	    UnGetReq(PutImage);
Packit 5bd3a9
	    return;
Packit 5bd3a9
	}
Packit 5bd3a9
Packit 5bd3a9
    if ((image->byte_order == dpy->byte_order) ||
Packit 5bd3a9
	(image->bits_per_pixel == 8))
Packit 5bd3a9
	NoSwap(src, dest, bytes_per_src, (long)image->bytes_per_line,
Packit 5bd3a9
	       bytes_per_dest, req->height, image->byte_order);
Packit 5bd3a9
    else if (image->bits_per_pixel == 32)
Packit 5bd3a9
	SwapFourBytes(src, dest, bytes_per_src, (long)image->bytes_per_line,
Packit 5bd3a9
		      bytes_per_dest, req->height, image->byte_order);
Packit 5bd3a9
    else if (image->bits_per_pixel == 24)
Packit 5bd3a9
	SwapThreeBytes(src, dest, bytes_per_src, (long)image->bytes_per_line,
Packit 5bd3a9
		       bytes_per_dest, req->height, image->byte_order);
Packit 5bd3a9
    else if (image->bits_per_pixel == 16)
Packit 5bd3a9
	SwapTwoBytes(src, dest, bytes_per_src, (long)image->bytes_per_line,
Packit 5bd3a9
		     bytes_per_dest, req->height, image->byte_order);
Packit 5bd3a9
    else
Packit 5bd3a9
	SwapNibbles(src, dest, bytes_per_src, (long)image->bytes_per_line,
Packit 5bd3a9
		    bytes_per_dest, req->height);
Packit 5bd3a9
Packit 5bd3a9
    if (dest == (unsigned char *)dpy->bufptr)
Packit 5bd3a9
	dpy->bufptr += length;
Packit 5bd3a9
    else
Packit 5bd3a9
	_XSend(dpy, (char *)dest, length);
Packit 5bd3a9
Packit 5bd3a9
    Xfree(shifted_src);
Packit 5bd3a9
}
Packit 5bd3a9
Packit 5bd3a9
static void
Packit 5bd3a9
PutImageRequest(
Packit 5bd3a9
    register Display *dpy,
Packit 5bd3a9
    Drawable d,
Packit 5bd3a9
    GC gc,
Packit 5bd3a9
    register XImage *image,
Packit 5bd3a9
    int req_xoffset, int req_yoffset,
Packit 5bd3a9
    int x, int y,
Packit 5bd3a9
    unsigned int req_width, unsigned int req_height,
Packit 5bd3a9
    int dest_bits_per_pixel, int dest_scanline_pad)
Packit 5bd3a9
{
Packit 5bd3a9
    register xPutImageReq *req;
Packit 5bd3a9
Packit 5bd3a9
    GetReq(PutImage, req);
Packit 5bd3a9
    req->drawable = d;
Packit 5bd3a9
    req->gc = gc->gid;
Packit 5bd3a9
    req->dstX = x;
Packit 5bd3a9
    req->dstY = y;
Packit 5bd3a9
    req->width = req_width;
Packit 5bd3a9
    req->height = req_height;
Packit 5bd3a9
    req->depth = image->depth;
Packit 5bd3a9
    req->format = image->format;
Packit 5bd3a9
    if ((image->bits_per_pixel == 1) || (image->format != ZPixmap))
Packit 5bd3a9
	SendXYImage(dpy, req, image, req_xoffset, req_yoffset);
Packit 5bd3a9
    else
Packit 5bd3a9
	SendZImage(dpy, req, image, req_xoffset, req_yoffset,
Packit 5bd3a9
		   dest_bits_per_pixel, dest_scanline_pad);
Packit 5bd3a9
}
Packit 5bd3a9
Packit 5bd3a9
static void
Packit 5bd3a9
PutSubImage (
Packit 5bd3a9
    register Display *dpy,
Packit 5bd3a9
    Drawable d,
Packit 5bd3a9
    GC gc,
Packit 5bd3a9
    register XImage *image,
Packit 5bd3a9
    int req_xoffset,
Packit 5bd3a9
    int req_yoffset,
Packit 5bd3a9
    int x, int y,
Packit 5bd3a9
    unsigned int req_width,
Packit 5bd3a9
    unsigned int req_height,
Packit 5bd3a9
    int dest_bits_per_pixel,
Packit 5bd3a9
    int dest_scanline_pad)
Packit 5bd3a9
{
Packit 5bd3a9
    int left_pad, BytesPerRow, Available;
Packit 5bd3a9
Packit 5bd3a9
    if ((req_width == 0) || (req_height == 0))
Packit 5bd3a9
	return;
Packit 5bd3a9
Packit 5bd3a9
    Available = ((65536 < dpy->max_request_size) ? (65536 << 2)
Packit 5bd3a9
						 : (dpy->max_request_size << 2))
Packit 5bd3a9
		- SIZEOF(xPutImageReq);
Packit 5bd3a9
Packit 5bd3a9
    if ((image->bits_per_pixel == 1) || (image->format != ZPixmap)) {
Packit 5bd3a9
	left_pad = (image->xoffset + req_xoffset) & (dpy->bitmap_unit - 1);
Packit 5bd3a9
	BytesPerRow = (ROUNDUP((long)req_width + left_pad,
Packit 5bd3a9
			       dpy->bitmap_pad) >> 3) * image->depth;
Packit 5bd3a9
    } else {
Packit 5bd3a9
	left_pad = 0;
Packit 5bd3a9
	BytesPerRow = ROUNDUP((long)req_width * dest_bits_per_pixel,
Packit 5bd3a9
			      dest_scanline_pad) >> 3;
Packit 5bd3a9
    }
Packit 5bd3a9
Packit 5bd3a9
    if ((BytesPerRow * req_height) <= Available) {
Packit 5bd3a9
        PutImageRequest(dpy, d, gc, image, req_xoffset, req_yoffset, x, y,
Packit 5bd3a9
			req_width, req_height,
Packit 5bd3a9
			dest_bits_per_pixel, dest_scanline_pad);
Packit 5bd3a9
    } else if (req_height > 1) {
Packit 5bd3a9
	int SubImageHeight = Available / BytesPerRow;
Packit 5bd3a9
Packit 5bd3a9
	if (SubImageHeight == 0)
Packit 5bd3a9
	    SubImageHeight = 1;
Packit 5bd3a9
Packit 5bd3a9
	PutSubImage(dpy, d, gc, image, req_xoffset, req_yoffset, x, y,
Packit 5bd3a9
		    req_width, (unsigned int) SubImageHeight,
Packit 5bd3a9
		    dest_bits_per_pixel, dest_scanline_pad);
Packit 5bd3a9
Packit 5bd3a9
	PutSubImage(dpy, d, gc, image, req_xoffset,
Packit 5bd3a9
		    req_yoffset + SubImageHeight, x, y + SubImageHeight,
Packit 5bd3a9
		    req_width, req_height - SubImageHeight,
Packit 5bd3a9
		    dest_bits_per_pixel, dest_scanline_pad);
Packit 5bd3a9
    } else {
Packit 5bd3a9
	int SubImageWidth = (((Available << 3) / dest_scanline_pad)
Packit 5bd3a9
				* dest_scanline_pad) - left_pad;
Packit 5bd3a9
Packit 5bd3a9
	PutSubImage(dpy, d, gc, image, req_xoffset, req_yoffset, x, y,
Packit 5bd3a9
		    (unsigned int) SubImageWidth, 1,
Packit 5bd3a9
		    dest_bits_per_pixel, dest_scanline_pad);
Packit 5bd3a9
Packit 5bd3a9
	PutSubImage(dpy, d, gc, image, req_xoffset + SubImageWidth,
Packit 5bd3a9
		    req_yoffset, x + SubImageWidth, y,
Packit 5bd3a9
		    req_width - SubImageWidth, 1,
Packit 5bd3a9
		    dest_bits_per_pixel, dest_scanline_pad);
Packit 5bd3a9
    }
Packit 5bd3a9
}
Packit 5bd3a9
Packit 5bd3a9
Packit 5bd3a9
int
Packit 5bd3a9
XPutImage (
Packit 5bd3a9
    register Display *dpy,
Packit 5bd3a9
    Drawable d,
Packit 5bd3a9
    GC gc,
Packit 5bd3a9
    register XImage *image,
Packit 5bd3a9
    int req_xoffset,
Packit 5bd3a9
    int req_yoffset,
Packit 5bd3a9
    int x,
Packit 5bd3a9
    int y,
Packit 5bd3a9
    unsigned int req_width,
Packit 5bd3a9
    unsigned int req_height)
Packit 5bd3a9
Packit 5bd3a9
{
Packit 5bd3a9
    long width = req_width;
Packit 5bd3a9
    long height = req_height;
Packit 5bd3a9
    int dest_bits_per_pixel, dest_scanline_pad;
Packit 5bd3a9
Packit 5bd3a9
    if (req_xoffset < 0) {
Packit 5bd3a9
	width += req_xoffset;
Packit 5bd3a9
	req_xoffset = 0;
Packit 5bd3a9
    }
Packit 5bd3a9
    if (req_yoffset < 0) {
Packit 5bd3a9
	height += req_yoffset;
Packit 5bd3a9
	req_yoffset = 0;
Packit 5bd3a9
    }
Packit 5bd3a9
    if ((req_xoffset + width) > image->width)
Packit 5bd3a9
	width = image->width - req_xoffset;
Packit 5bd3a9
    if ((req_yoffset + height) > image->height)
Packit 5bd3a9
	height = image->height - req_yoffset;
Packit 5bd3a9
    if ((width <= 0) || (height <= 0))
Packit 5bd3a9
	return 0;
Packit 5bd3a9
Packit 5bd3a9
    if ((image->bits_per_pixel == 1) || (image->format != ZPixmap)) {
Packit 5bd3a9
	dest_bits_per_pixel = 1;
Packit 5bd3a9
	dest_scanline_pad = dpy->bitmap_pad;
Packit 5bd3a9
    } else {
Packit 5bd3a9
	register int n;
Packit 5bd3a9
	register ScreenFormat *format;
Packit 5bd3a9
Packit 5bd3a9
	dest_bits_per_pixel = image->bits_per_pixel;
Packit 5bd3a9
	dest_scanline_pad = image->bitmap_pad;
Packit 5bd3a9
	for (n = dpy->nformats, format = dpy->pixmap_format; --n >= 0; format++)
Packit 5bd3a9
	    if (format->depth == image->depth) {
Packit 5bd3a9
		dest_bits_per_pixel = format->bits_per_pixel;
Packit 5bd3a9
		dest_scanline_pad = format->scanline_pad;
Packit 5bd3a9
	    }
Packit 5bd3a9
	if (dest_bits_per_pixel != image->bits_per_pixel) {
Packit 5bd3a9
	    XImage img;
Packit 5bd3a9
	    register long i, j;
Packit 5bd3a9
	    /* XXX slow, but works */
Packit 5bd3a9
	    img.width = width;
Packit 5bd3a9
	    img.height = height;
Packit 5bd3a9
	    img.xoffset = 0;
Packit 5bd3a9
	    img.format = ZPixmap;
Packit 5bd3a9
	    img.byte_order = dpy->byte_order;
Packit 5bd3a9
	    img.bitmap_unit = dpy->bitmap_unit;
Packit 5bd3a9
	    img.bitmap_bit_order = dpy->bitmap_bit_order;
Packit 5bd3a9
	    img.bitmap_pad = dest_scanline_pad;
Packit 5bd3a9
	    img.depth = image->depth;
Packit 5bd3a9
	    img.bits_per_pixel = dest_bits_per_pixel;
Packit 5bd3a9
	    img.bytes_per_line = ROUNDUP((dest_bits_per_pixel * width),
Packit 5bd3a9
					 dest_scanline_pad) >> 3;
Packit 5bd3a9
	    img.data = Xmallocarray(height, img.bytes_per_line);
Packit 5bd3a9
	    if (img.data == NULL)
Packit 5bd3a9
		return 0;
Packit 5bd3a9
	    _XInitImageFuncPtrs(&img;;
Packit 5bd3a9
	    for (j = height; --j >= 0; )
Packit 5bd3a9
		for (i = width; --i >= 0; )
Packit 5bd3a9
		    XPutPixel(&img, i, j, XGetPixel(image, req_xoffset + i,
Packit 5bd3a9
						    req_yoffset + j));
Packit 5bd3a9
	    LockDisplay(dpy);
Packit 5bd3a9
	    FlushGC(dpy, gc);
Packit 5bd3a9
	    PutSubImage(dpy, d, gc, &img, 0, 0, x, y,
Packit 5bd3a9
			(unsigned int) width, (unsigned int) height,
Packit 5bd3a9
			dest_bits_per_pixel, dest_scanline_pad);
Packit 5bd3a9
	    UnlockDisplay(dpy);
Packit 5bd3a9
	    SyncHandle();
Packit 5bd3a9
	    Xfree(img.data);
Packit 5bd3a9
	    return 0;
Packit 5bd3a9
	}
Packit 5bd3a9
    }
Packit 5bd3a9
Packit 5bd3a9
    LockDisplay(dpy);
Packit 5bd3a9
    FlushGC(dpy, gc);
Packit 5bd3a9
Packit 5bd3a9
    PutSubImage(dpy, d, gc, image, req_xoffset, req_yoffset, x, y,
Packit 5bd3a9
		(unsigned int) width, (unsigned int) height,
Packit 5bd3a9
		dest_bits_per_pixel, dest_scanline_pad);
Packit 5bd3a9
Packit 5bd3a9
    UnlockDisplay(dpy);
Packit 5bd3a9
    SyncHandle();
Packit 5bd3a9
#ifdef USE_DYNAMIC_XCURSOR
Packit 5bd3a9
    if (image->bits_per_pixel == 1 &&
Packit 5bd3a9
	x == 0 && y == 0 &&
Packit 5bd3a9
	width == image->width && height == image->height &&
Packit 5bd3a9
	gc->values.function == GXcopy &&
Packit 5bd3a9
	(gc->values.plane_mask & 1))
Packit 5bd3a9
    {
Packit 5bd3a9
	_XNoticePutBitmap (dpy, d, image);
Packit 5bd3a9
    }
Packit 5bd3a9
#endif
Packit 5bd3a9
    return 0;
Packit 5bd3a9
}