home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The World of Computer Software
/
World_Of_Computer_Software-02-385-Vol-1of3.iso
/
x
/
xibm.zip
/
mpel
/
mpelPutImage.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-07-06
|
5KB
|
206 lines
/**/
#include "X.h"
#include "gcstruct.h"
#include "pixmapstr.h"
#include "windowstr.h"
#include "scrnintstr.h"
#include "servermd.h"
#include "mi.h"
#include "ppc.h"
#include "mpel.h"
#include "mpelFifo.h"
#include "ibmTrace.h"
extern int mfbGCPrivateIndex;
extern void mpel4x4(); /* This is also used by cursor code */
/* Put Image optimized for megapel
* (partially stolen from cfbPutImage)
*/
void mpelPutImage(pDrawable, pGC, depth, x, y, w, h, leftPad, format, pImage)
DrawablePtr pDrawable;
GCPtr pGC;
unsigned int depth, w, h, format;
int x, y, leftPad;
unsigned char *pImage;
{
unsigned int nbytes;
ppcPrivGC *pPriv;
BoxRec b;
int inters;
RegionPtr pRegion;
if(w == 0 || h == 0)
return;
b.x1 = pDrawable->x + x;
b.x2 = pDrawable->x + x + w - 1;
b.y1 = pDrawable->y + y;
b.y2 = pDrawable->y + y + h - 1;
pPriv = (ppcPrivGC *)pGC->devPrivates[mfbGCPrivateIndex].ptr;
pRegion = pPriv->pCompositeClip;
if(REGION_NIL(pRegion))
return;
inters = miRectIn(pRegion, &b);
if(inters == rgnOUT)
return;
if(pDrawable->type == DRAWABLE_PIXMAP || format == XYPixmap ||
inters == rgnPART || pDrawable->y + h + 4 > MPEL_HEIGHT)
{
miPutImage(pDrawable, pGC, depth, x, y, w, h, leftPad, format, pImage);
return;
}
/* After here, it is known that the image destination is unclipped */
nbytes = (w * h * depth + 15) / 8;
nbytes &= ~1;
TRACE(("mpelPutImage(... %d, %d, %d, %d, %d ...) nbytes %d\n",
x, y, w, h, leftPad, nbytes));
/* If the image is larger than the max request size, use the slow method */
if (depth > 1 || nbytes > 32700)
{
int saveexp;
PixmapRec pm;
pm.drawable.type = DRAWABLE_PIXMAP;
pm.drawable.class = 0;
pm.drawable.pScreen = pDrawable->pScreen;
pm.drawable.bitsPerPixel = pm.drawable.depth = depth;
pm.drawable.id = 0;
pm.drawable.serialNumber = NEXT_SERIAL_NUMBER;
pm.drawable.x = pm.drawable.y = 0;
pm.drawable.width = w + leftPad;
pm.drawable.height = h;
pm.devKind = PixmapBytePad(pm.drawable.width, depth);
pm.refcnt = 1;
pm.devPrivate.ptr = (pointer)pImage;
saveexp = pPriv->fExpose;
((ppcPrivGC *)pGC->devPrivates[mfbGCPrivateIndex].ptr)->fExpose = 0;
if (format == ZPixmap)
(void) (*pGC->ops->CopyArea)(&pm, pDrawable, pGC, leftPad, 0, w, h, x, y);
else
(void) (*pGC->ops->CopyPlane)(&pm, pDrawable, pGC, leftPad, 0, w, h, x, y, 1);
pPriv->fExpose = saveexp;
} else {
short *fbits; /* data formatted for megapel adapter */
int dw, dh, adj;
mpelRectangle r;
mpelBLTImmed4x4WColorExpansion cmd;
dw = (w + 7) & ~7;
dh = (h + 7) & ~7;
nbytes = dw * dh / 8;
/* adj is the amount by which the destination area must be
moved to compensate for mpel4x4 padding the bottom edge
of the image with blanks */
adj = (4 - (h & 3)) & 3;
fbits = ALLOCATE_LOCAL(nbytes);
bzero(fbits, nbytes);
mpel4x4(pImage, w, h, fbits);
/* Must keep LLC (based on orignal h) */
r.lleft.x = cmd.dest.lleft.x = pDrawable->x + x;
r.lleft.y = MPEL_HEIGHT - pDrawable->y - y - h;
cmd.dest.lleft.y = r.lleft.y - adj;
r.uright.x = pDrawable->x + x + w - 1;
cmd.dest.uright.x = pDrawable->x + x + dw - 1;
cmd.dest.uright.y = MPEL_HEIGHT - pDrawable->y - y - h + dh - 1 - adj;
r.uright.y = MPEL_HEIGHT - pDrawable->y - 1;
cmd.color = pGC->fgPixel;
TRACE(("\t{%d,%d},{%d,%d}\n",
cmd.dest.lleft.x, cmd.dest.lleft.y,
cmd.dest.uright.x, cmd.dest.uright.y));
MPELBLTImmed4x4WColorExpansion(nbytes, &cmd);
MPELSendData(nbytes, fbits);
DEALLOCATE_LOCAL(fbits);
}
}
/* Take a pointer to bitmap data, and format it into a set of 4x4 blocks
* suitable for use with mpel blt vpm 4x4 w/ color expansion.
*
* bits -- source data
* dst -- where to put formatted bits (round up size to multiple of 4)
* sw, sh -- source dimensions
*/
union i4c { unsigned int i;
unsigned char c[4];
};
#define EXT(dst, i) *dst ++ = ((i & 0xf0000000) >> 16) | ((i & 0x00f00000) >> 12) | ((i & 0x0000f000) >> 8) | ((i & 0x000000f0) >> 4);\
*dst++ = ((i & 0x0f000000) >> 12) | ((i & 0x000f0000) >> 8) | ((i & 0x00000f00) >> 4) | (i & 0x0000000f);
void mpel4x4(bits, sw, sh, dst)
char *bits;
short *dst;
int sw, sh;
{
int dw = (sw + 7) & ~7;
int dh = (sh + 7) & ~7;
int xc, yc;
int src_al = ((sw + 7) / 8 + 3) & ~3;
TRACE(("mpel4x4(%#x, %d, %d, %#x) src_al %d dw %d dh %d\n",
bits, sw, sh, dst, src_al, dw, dh));
if(sh & 3)
{
yc = (sh & ~3);
for(xc = 0; xc < (dw >> 3); xc++)
{
register unsigned int i;
register int yoff = yc * src_al;
union i4c u;
u.i = 0;
switch(sh & 3)
{
case 3:
/* *(bits + xc + (yc + 2) * src_al) */
u.c[2] = *(bits + xc + yoff + src_al + src_al);
case 2:
/* *(bits + xc + (yc + 1) * src_al) */
u.c[1] = *(bits + xc + yoff + src_al);
case 1:
u.c[0] = *(bits + xc + yoff);
}
i = u.i;
EXT(dst, i)
}
}
for(yc = (sh-4)&~3; yc >= 0; yc -= 4)
{
for(xc = 0; xc < (dw>>3); xc++)
{
register unsigned int i;
union i4c u;
u.c[0] = *(bits + xc + yc * src_al);
u.c[1] = *(bits + xc + (yc + 1) * src_al);
u.c[2] = *(bits + xc + (yc + 2) * src_al);
u.c[3] = *(bits + xc + (yc + 3) * src_al);
i = u.i;
EXT(dst, i)
}
}
}