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
/
mpelStip.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-07-23
|
20KB
|
736 lines
/* */
#include "X.h"
#include "Xproto.h"
#include "Xmd.h"
#include "servermd.h"
#include "pixmapstr.h"
#include "gcstruct.h"
#include "colormap.h" /* needed by ppc */
#include "regionstr.h"
#include "mi.h"
#include "OScompiler.h"
#include "ibmTrace.h"
#include "mpel.h"
#include "mpelHdwr.h"
#include "mpelFifo.h"
#include "ppcGCstr.h"
extern PixmapPtr ppcCopyPixmap();
extern void mpelStippleWindowFS();
static void mpelStippleWindowFS2();
static void make4x4();
static BoxPtr mpel4x4rgn();
#ifdef PROFILE
#undef MPELSendData
#define MPELSendData(n, d) data_glue(d, n)
void data_glue(d, n)
register void *d;
register unsigned int n;
{
mfData(d, n);
}
#endif
/* If the operation is GXcopy and the data can fit into a megapel adapter
command (i.e. size can fit in a signed short), then use the 4x4 Immediate
Blit w/ color expansion. Otherwise, copy it to the stage area.
In any case, to make things simple the source width is rounded to a
multiple of 32 bits (note: check performance hit) for storage in the
stage area.
What would be nice is a way to lock the pages into physical memory and
pass that to the adapter...
*/
#ifdef TRACE_X
static char *gxnames[] = {
"GXcopy",
"GXand",
"GXandReverse",
"GXcopy",
"GXandInverted",
"GXnoop",
"GXxor",
"GXor",
"GXnor",
"GXequiv",
"GXinvert",
"GXorReverse",
"GXcopyInverted",
"GXorInverted",
"GXnand",
"GXset",
};
#endif
void
mpelStipple(pStipple, fg, alu, planes, x, y, w, h, xSrc, ySrc)
PixmapPtr pStipple;
unsigned long int fg;
int alu;
unsigned long int planes;
int x, y, w, h;
int xSrc, ySrc;
{
mpelStippleFillRegion(0, pStipple, fg, alu, planes, x, y, w, h, xSrc, ySrc);
return;
}
void mpelOpStipple(pStipple, fg, bg, alu, planes, x, y, w, h, xSrc, ySrc)
PixmapPtr pStipple;
unsigned long int fg, bg;
int alu;
unsigned long int planes;
int x, y, w, h;
int xSrc, ySrc;
{
switch(alu)
{
case GXnoop:
break;
case GXclear:
case GXset:
mpelFillSolid(fg, alu, planes, x, y, w, h);
break;
case GXcopy:
case GXcopyInverted:
mpelFillSolid(bg, alu, planes, x, y, w, h);
mpelStippleFillRegion(0, pStipple, fg, alu, planes, x, y, w, h, xSrc, ySrc);
break;
default:
{
register int i, j;
register PixmapPtr pInvStipple = ppcCopyPixmap(pStipple);
register unsigned char *data = pInvStipple->devPrivate.ptr;
for (i = pInvStipple->drawable.height ; i-- ;)
for (j = pInvStipple->devKind ; j-- ; data++)
*data = ~*data;
mpelStippleFillRegion(0, pInvStipple, bg, alu,
planes, x, y, w, h, xSrc, ySrc);
mfbDestroyPixmap(pInvStipple);
mpelStippleFillRegion(0, pStipple, fg, alu,
planes, x, y, w, h, xSrc, ySrc);
}
}
}
#ifdef TRACE_X
static int trace_FS;
#endif
void
mpelOpStippleWindowFS(pDrawable, pGC, nSpans, ppts, pwidth, fSorted)
DrawablePtr pDrawable;
GC *pGC;
int nSpans;
DDXPointPtr ppts;
int *pwidth;
int fSorted;
{
int alu;
unsigned long fg, bg;
ppcPrivGC *pPriv = (ppcPrivGC *) pGC->devPrivates[mfbGCPrivateIndex].ptr;
fg = pPriv->colorRrop.fgPixel;
bg = pPriv->colorRrop.bgPixel;
alu = pPriv->colorRrop.alu;
#ifdef TRACE_X
if(ibmTrace && trace_FS)
ErrorF("mpelOpStippleWindowFS(%#x, %#x, %d, %#x, %#x) alu %s fg %d bg %d\n",
pDrawable, pGC, nSpans, ppts, pwidth, gxnames[alu], fg, bg);
#endif
switch(alu)
{
case GXnoop:
break;
/* The following are degenerate */
case GXclear:
case GXset:
ppcSolidWindowFS(pDrawable, pGC, nSpans, ppts, pwidth, fSorted);
break;
/* These are easy */
case GXcopy:
case GXcopyInverted:
/* Hack alert! */
pPriv->colorRrop.fgPixel = bg;
ppcSolidWindowFS(pDrawable, pGC, nSpans, ppts, pwidth, fSorted);
pPriv->colorRrop.fgPixel = fg;
mpelStippleWindowFS2(pGC->stipple, 0,
pDrawable->x + pGC->patOrg.x,
pDrawable->y + pGC->patOrg.y, pPriv,
nSpans, ppts, pwidth, fSorted);
break;
/* These are hard */
default:
{
/* Create an inverted stipple for the background */
register int i, j;
register PixmapPtr pInvStipple = ppcCopyPixmap(pGC->stipple);
register unsigned char *data = pInvStipple->devPrivate.ptr;
for (i = pInvStipple->drawable.height ; i-- ;)
for (j = pInvStipple->devKind ; j-- ; data++)
*data = ~*data;
mpelStippleWindowFS2(pGC->stipple, pInvStipple,
pDrawable->x + pGC->patOrg.x,
pDrawable->y + pGC->patOrg.y, pPriv,
nSpans, ppts, pwidth, fSorted);
mfbDestroyPixmap(pInvStipple);
}
break;
}
}
void
mpelStippleWindowFS(pDrawable, pGC, nSpans, ppts, pwidth, fSorted)
DrawablePtr pDrawable;
GC *pGC;
int nSpans;
DDXPointPtr ppts;
int *pwidth;
int fSorted;
{
ppcPrivGC *pPriv = (ppcPrivGC *) pGC->devPrivates[mfbGCPrivateIndex].ptr;
#ifdef TRACE_X
if(ibmTrace && trace_FS)
ErrorF("mpelStippleWindowFS(%#x, %#x, %d, %#x, %#x, %d)\n",
pDrawable, pGC, nSpans, ppts, pwidth, fSorted);
#endif
mpelStippleWindowFS2(pGC->stipple, 0, pDrawable->x + pGC->patOrg.x,
pDrawable->y + pGC->patOrg.y, pPriv,
nSpans, ppts, pwidth, fSorted);
}
static void
mpelStippleWindowFS2(pStippleF, pStippleB, xSrc, ySrc,
pPriv, nSpans, ppts, pwidth, fSorted)
PixmapPtr pStippleF, pStippleB;
int nSpans, xSrc, ySrc;
DDXPointPtr ppts;
int *pwidth;
int fSorted;
ppcPrivGC *pPriv;
{
RegionPtr Rfill, pClip = pPriv->pCompositeClip;
int alu;
unsigned long fg, bg;
fg = pPriv->colorRrop.fgPixel;
bg = pPriv->colorRrop.bgPixel;
alu = pPriv->colorRrop.alu;
if(alu == GXnoop || REGION_NUM_RECTS(pClip) == 0)
return;
{
Bool overlap;
register int i;
register xRectangle *rects;
xRectangle *rectsInit =
(xRectangle *)ALLOCATE_LOCAL(nSpans * sizeof(xRectangle));
register DDXPointPtr p = ppts;
int *w = pwidth;
rects = rectsInit;
for(i = 0;i < nSpans;i++)
{
if(i && p->x == (p-1)->x && p->y == ((p-1)->y + 1) && *w == *(w-1))
{
(rects-1)->height++;
} else {
rects->x = p->x;
rects->y = p->y;
rects->width = *w;
rects->height = 1;
rects++;
}
p++;
w++;
}
Rfill = miRectsToRegion(rects - rectsInit, rectsInit,
fSorted ? CT_YXBANDED : CT_UNSORTED);
DEALLOCATE_LOCAL(rectsInit);
miRegionValidate(Rfill, &overlap);
if(miIntersect(Rfill, Rfill, pClip) == FALSE)
{
ErrorF("mpelStippleFillSpans: Error in clip intersect");
miRegionDestroy(Rfill);
return;
}
}
/* Now Rfill is a region to be entirely filled with stipple */
if(pStippleB)
mpelStippleFillRegion(Rfill, pStippleB, bg, alu, pPriv->colorRrop.planemask,
-1, -1, -1, -1, xSrc, ySrc);
if(pStippleF)
mpelStippleFillRegion(Rfill, pStippleF, fg, alu, pPriv->colorRrop.planemask,
-1, -1, -1, -1, xSrc, ySrc);
miRegionDestroy(Rfill);
}
void
mpelStippleFillRect(pDrawable, pGC, nrect, prect)
DrawablePtr pDrawable;
GCPtr pGC;
int nrect;
xRectangle *prect;
{
RegionPtr fillRgn;
ppcPrivGC *pPriv = (ppcPrivGC *)pGC->devPrivates[mfbGCPrivateIndex].ptr;
Bool overlap;
TRACE(("mpelStippleFillRect(%#x, %#x, %d, %#x)\n",pDrawable,pGC,nrect,prect));
fillRgn = miRectsToRegion(nrect, prect, CT_UNSORTED);
miRegionValidate(fillRgn, &overlap);
miTranslateRegion(fillRgn, pDrawable->x, pDrawable->y);
miIntersect(fillRgn, fillRgn, pPriv->pCompositeClip);
miRegionValidate(fillRgn, &overlap);
mpelStippleFillRegion(fillRgn, pGC->stipple, pPriv->colorRrop.fgPixel,
pPriv->colorRrop.alu, pGC->planemask,
-1, -1, -1, -1, pDrawable->x, pDrawable->y);
miRegionDestroy(fillRgn);
}
#ifdef TRACE_X
int __verbose_trace;
#endif
static xPoint *stpts;
static int stptcnt;
mpelStippleFillRegion(pRgn, pStipple, fg, alu, planes, x, y, w, h, xSrc, ySrc)
RegionPtr pRgn;
PixmapPtr pStipple;
int xSrc, ySrc, alu, x, y;
unsigned int w, h;
unsigned long fg, planes;
{
register unsigned char *bits;
int padded_h, nbytes, fast;
unsigned int src_al, dest_al;
RegionRec r;
int need_to_free = 0; /* Need to unInit temp region ? */
#ifdef TRACE_X
if(pRgn)
{
TRACE(("mpelStippleFillRegion({%d, %d} {%d, %d}, {%dx%d}, fg %d %s)\n",
pRgn->extents.x1, pRgn->extents.y1, pRgn->extents.x2,
pRgn->extents.y2, pStipple->drawable.width,
pStipple->drawable.height,fg, gxnames[alu]));
} else {
TRACE(("mpelStippleFillRegion(%d, %d, %d, %d, {%dx%d}, fg %d %s)\n",
x, y, w, h, pStipple->drawable.width,
pStipple->drawable.height,fg, gxnames[alu]));
}
#endif
switch(alu)
{
case GXnoop:
return;
case GXclear:
alu = GXcopy;
fg = 0;
break;
case GXset:
alu = GXcopy;
fg = ~0;
break;
case GXcopyInverted:
alu = GXcopy;
fg = ~fg;
break;
}
if(w != -1 && h != -1)
{
BoxRec b;
Bool overlap;
b.x1 = x;
b.x2 = x + w - 1;
b.y1 = y;
b.y2 = y + h - 1;
miRegionInit(&r, &b, 0);
if(pRgn)
miIntersect(&r, &r, pRgn);
pRgn = &r;
miRegionValidate(pRgn, &overlap);
need_to_free = 1;
}
/* At this point pRgn is a list of rectangles to be completely
filled with the stipple pattern. x, y, w, and h can be
ignored. */
src_al = pStipple->devKind;
/* dest_al is the number of 4-bit pieces that need to be read.
To simplify later calculations, make it be a multiple of 2. */
dest_al = ((pStipple->drawable.width + 7) >> 3) << 1;
padded_h = (pStipple->drawable.height + 3) & ~3;
/* Can the output data fit into a megapel adapter command ? */
fast = ((nbytes = padded_h * dest_al / 2) < 0x7ff0) && (alu == GXcopy);
if(!fast)
{
padded_h = pStipple->drawable.height;
if((nbytes = src_al * padded_h / 8) > MPEL_BLIT_STAGE_SIZE)
{
ErrorF("mpelStipple: stipple too big\n");
return;
}
}
mpelSetPlaneMask(planes);
ySrc %= pStipple->drawable.height;
if(ySrc < 0)
ySrc += pStipple->drawable.height;
xSrc %= pStipple->drawable.width;
if(xSrc < 0)
xSrc += pStipple->drawable.width;
bits = pStipple->devPrivate.ptr;
if(fast)
{
mpelBLTImmed4x4WColorExpansion d;
mpelRectangle scissor;
BoxPtr rect4x4;
unsigned short *stage = (unsigned short *)ALLOCATE_LOCAL(nbytes);
register unsigned short *dst = stage;
register int xc, yc;
unsigned int i;
int pused = 0;
int sh = pStipple->drawable.height;
int sw = pStipple->drawable.width;
int nboxes;
d.color = fg;
make4x4(bits, dst, &sw, &sh, src_al, dest_al * 4, xSrc, ySrc);
rect4x4 = mpel4x4rgn(pRgn, &nboxes);
for(i = 0;i < nboxes; i++)
{
BoxPtr b = rect4x4 + i;
#ifdef TRACE_X
if(__verbose_trace)
TRACE(("region {%d,%d}, {%d,%d} data [%x %x ...]\n",
b->x1, b->y1, b->x2, b->y2, stage[0], stage[1]));
#endif
scissor.uright.x = b->x2;
scissor.lleft.x = b->x1;
scissor.uright.y = MPEL_HEIGHT - 1 - b->y1;
scissor.lleft.y = MPEL_HEIGHT - b->y2;
MPELSetScissor(&scissor);
/* Optimize points. A bit of the source is
bits + (src_al * y) + x / 8 : x % 8 */
if(b->x1 == b->x2 && b->y1 + 1 <= b->y2)
{
register int xoff, yoff;
xoff = (b->x1 - xSrc) % sw;
yoff = (b->y1 - ySrc) % sh;
if(xoff < 0)
xoff += sw;
if(yoff < 0)
yoff += sw;
if(bits[src_al * yoff + x / 8] & (0x80 >> (x & 7)))
{
if(pused >= stptcnt)
stpts = (xPoint *)Xrealloc(stpts, sizeof(xPoint) * (stptcnt = pused + 48));
stpts[pused].x = b->x1;
stpts[pused].y = MPEL_HEIGHT - 1 - b->y1;
pused++;
}
continue;
}
/* The megapel scissor hardware requires that the low 2 bits
of the lower left corner of the scissor region be the same
as those of the box being filled, else the scissor boundary
may be off by up to 3 bits. The following code needs to be
fixed to compensate for this. */
for(xc = (b->x1/sw)*sw;xc < b->x2; xc += sw)
for(yc = (b->y1/sh)*sh;yc < b->y2; yc += sh)
{
unsigned int tmpy = (b->y2 - yc + 2) & ~3;
unsigned int tmpnb;
if(tmpy > padded_h)
tmpy = padded_h;
tmpnb = dest_al / 2 * tmpy;
#ifdef TRACE_X
if(__verbose_trace)
TRACE(("\tnbytes = %d, tmpy = %d\n", tmpnb, tmpy));
#endif
d.dest.lleft.x = xc;
d.dest.lleft.y = MPEL_HEIGHT - yc - tmpy;
d.dest.uright.x = xc + dest_al * 4 - 1;
d.dest.uright.y = MPEL_HEIGHT - yc - 1;
MPELBLTImmed4x4WColorExpansion(tmpnb, &d);
MPELSendData(tmpnb, (char *)stage);
}
}
if(pused)
{
#define MAXRQPTS (32760 / sizeof(xPoint))
register int rem;
register xPoint *pts = stpts;
MPELResetScissor();
MPELSetMarkerType(1);
MPELSetPolymarkerColor(fg);
/* MPELPolymarker does not evaluate any of its arguments
more than once. */
for(rem = pused;rem > 0;rem -= MAXRQPTS, pts+=MAXRQPTS)
MPELPolymarker((rem>MAXRQPTS)?MAXRQPTS:rem, pts);
TRACE(("mpelStipple: %d extra points\n", pused));
}
DEALLOCATE_LOCAL((char *)stage);
} else { /* ! fast */
mpelSrcBLTVPMWColorExpansion block;
register unsigned int sh = pStipple->drawable.height;
register unsigned int sw = pStipple->drawable.width;
register int xc, yc;
int i;
block.color = fg;
block.alu = alu + 1;
block.srcaddr = mpelAddr(MPEL_BLIT_STAGE);
MPELWaitFifo(); /* Don't copy into stage area until sure
no one else is using it. */
MOVE(bits, MPEL_BLIT_STAGE, src_al * sh);
TRACE(("mpel slow stipple: org {%d, %d} source {%d, %d} src_al %d\n",
x, y, sw, sh, src_al));
for(i = 0;i < REGION_NUM_RECTS(pRgn); i++)
{
mpelRectangle scissor;
BoxPtr b = REGION_RECTS(pRgn)+i;
scissor.uright.x = b->x2;
scissor.lleft.x = b->x1;
scissor.uright.y = MPEL_HEIGHT - 1 - b->y1;
scissor.lleft.y = MPEL_HEIGHT - b->y2;
MPELSetScissor(&scissor);
for(xc = (b->x1 - xSrc)/sw + xSrc;xc < b->x2;xc += sw)
for(yc = (b->y1 - ySrc)/sh + ySrc;yc < b->y2;yc += sh)
{
block.dest.lleft.x = xc;
block.dest.lleft.y = MPEL_HEIGHT - yc - sh;
block.dest.uright.x = xc + (src_al << 3) - 1;
block.dest.uright.y = MPEL_HEIGHT - yc - 1;
MPELSrcBLTVPMWColorExpansionROP(&block);
}
}
}
MPELResetScissor();
if(need_to_free)
miRegionUninit(pRgn);
}
static void make4x4(bits, dst, sw, sh, src_al, dw, xOrg, yOrg)
char *bits;
short *dst;
int *sw, *sh, dw, src_al;
int xOrg, yOrg;
{
int dh = (*sh + 3) & ~3;
int xc, yc;
bzero((char *)dst, dh * dw >> 3);
if(*sh & 3)
{
register int off = 0;
yc = (*sh & ~3);
for(xc = 0; xc < (dw >> 3); xc++)
{
register unsigned int i;
union { unsigned int i;
unsigned char c[4];
} u;
u.i = 0;
switch(*sh & 3)
{
case 2:
u.c[3] = u.c[1] = *(bits + off + ((yc + yOrg + 1) % *sh) * src_al);
u.c[2] = u.c[0] = *(bits + off + ((yc + yOrg) % *sh) * src_al);
*sh = 4;
break;
case 3:
u.c[2] = *(bits + off + ((yc + yOrg + 2) % *sh) * src_al);
u.c[1] = *(bits + off + ((yc + yOrg + 1) % *sh) * src_al);
u.c[0] = *(bits + off + ((yc + yOrg) % *sh) * src_al);
break;
case 1:
u.c[0] = u.c[1] = u.c[2] = u.c[3] =
*(bits + off + ((yc + yOrg) % *sh) * src_al);
*sh = 4;
}
switch(*sw)
{
case 2:
u.i |= u.i >> 2;
case 4:
u.i |= u.i >> 4;
}
i = u.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);
off++;
}
}
for(yc = ((*sh-4)&~3); yc >= 0; yc -= 4)
{
register int off = 0;
for(xc = 0; xc < (dw>>3); xc++)
{
register unsigned int i;
union { unsigned int i;
unsigned char c[4];
} u;
u.c[0] = *(bits + off + ((yc + yOrg) % *sh) * src_al);
u.c[1] = *(bits + off + ((yc + yOrg + 1) % *sh) * src_al);
u.c[2] = *(bits + off + ((yc + yOrg + 2) % *sh) * src_al);
u.c[3] = *(bits + off + ((yc + yOrg + 3) % *sh) * src_al);
switch(*sw)
{
case 2:
u.i |= u.i >> 2;
case 4:
u.i |= u.i >> 4;
}
i = u.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);
off++;
}
}
if(*sw == 2 || *sw == 4)
*sw = 8;
}
/* mpel4x4rgn -- transform a validated region into a set of
* rectangles, creating as many rectangles with height a multiple
* of 4 as possible.
*
* xorg, yorg, sw and sh are hints: making a box bigger is not useful
* if it is made to cross a boundary s[wh] = 0 mod [xy]org.
*
* "4x4" is really a lie at this point...I'll settle for anything big.
*/
static BoxPtr mpel4x4rgn(pRgn, ret, sw, sh, xorg, yorg)
RegionPtr pRgn;
int *ret, xorg, yorg;
unsigned int sw, sh;
{
#if 1
*ret = REGION_NUM_RECTS(pRgn);
return REGION_RECTS(pRgn);
#else
int i, nrect;
BoxPtr prect, prectl;
int dx1, dx2;
prect = REGION_RECTS(pRgn);
/* Assume it's not worth optimizing regions that have a small
number of rectangles. */
if((nrect = REGION_NUM_RECTS(pRgn)) < 8)
{
*ret = nrect;
return prect;
}
if((i = nrect * 3) > n4x4boxes || n4x4boxes == 0)
if((mpel4x4boxes = (BoxPtr) Xrealloc(mpel4x4boxes,
sizeof(BoxRec) * (n4x4boxes = i))) == 0)
{
ErrorF("mpel4x4rgn: couldn't realloc %d boxes\n", i);
*ret = nrect;
n4x4boxes = 0;
return prect;
}
i = 0;
prectl = prect + nrect - 1;
do
{
register BoxPtr prectn;
/* Check for: boxes adjacent vertically, sides within 2 pixels */
if(prect < prectl && (prectn = prect + 1)->y1 == prect->y2 &&
prect->y2 - prect->y1 < 3 && prectn->y2 - prectn->y1 < 3 &&
prect->x2 - prect->x1 > 7 &&
(dx1 = prectn->x1 - prect->x1) > -3 && dx1 < 3 &&
(dx2 = prectn->x2 - prect->x2) > -3 && dx2 < 3)
{
if(dx1 > 0)
{
mpel4x4boxes[i].x1 = prect->x1;
mpel4x4boxes[i].x2 = prectn->x1 - 1;
mpel4x4boxes[i].y1 = prect->y1;
mpel4x4boxes[i++].y2 = prect->y2;
} else if(dx1 < 0) {
mpel4x4boxes[i].x1 = prectn->x1;
mpel4x4boxes[i].x2 = prect->x1 - 1;
mpel4x4boxes[i].y1 = prectn->y1;
mpel4x4boxes[i++].y2 = prectn->y2;
}
if(dx2 < 0)
{
mpel4x4boxes[i].x1 = prectn->x2 + 1;
mpel4x4boxes[i].x2 = prect->x2;
mpel4x4boxes[i].y1 = prect->y1;
mpel4x4boxes[i++].y2 = prect->y2;
} else if(dx2 > 0) {
mpel4x4boxes[i].x1 = prect->x2 + 1;
mpel4x4boxes[i].x2 = prectn->x2;
mpel4x4boxes[i].y1 = prectn->y1;
mpel4x4boxes[i++].y2 = prectn->y2;
}
mpel4x4boxes[i].x1 = (dx1 < 0) ? prect->x1 : prectn->x1;
mpel4x4boxes[i].x2 = (dx2 > 0) ? prect->x2 : prectn->x2;
mpel4x4boxes[i].y1 = prect->y1;
mpel4x4boxes[i++].y2 = prectn->y2;
prect += 2;
} else {
mpel4x4boxes[i++] = *prect++;
}
} while(prect <= prectl);
*ret = i;
#ifdef TRACE_X
if(ibmTrace && mpel4x4verbose)
ErrorF("mpel4x4rgn(%#x) returns %d\n", pRgn, i);
if(ibmTrace && mpel4x4verbose > 1)
while(i--)
ErrorF("mpel4x4boxes[%d] = %d x %d {%d, %d}, {%d, %d}\n",
i, mpel4x4boxes[i].x2 - mpel4x4boxes[i].x1,
mpel4x4boxes[i].y2 - mpel4x4boxes[i].y1,
mpel4x4boxes[i].x1, mpel4x4boxes[i].y1,
mpel4x4boxes[i].x2, mpel4x4boxes[i].y2);
#endif
return mpel4x4boxes;
#endif
}