executor/src/qIMVI.c

168 lines
4.7 KiB
C

/* Copyright 1994, 1995 by Abacus Research and
* Development, Inc. All rights reserved.
*/
#if !defined (OMIT_RCSID_STRINGS)
char ROMlib_rcsid_qIMVI[] =
"$Id: qIMVI.c 63 2004-12-24 18:19:43Z ctm $";
#endif
/* Forward declarations in QuickDraw.h (DO NOT DELETE THIS LINE) */
#include "rsys/common.h"
#include "QuickDraw.h"
#include "CQuickDraw.h"
#include "MemoryMgr.h"
#include "rsys/quick.h"
#include "rsys/pstuff.h"
#include "rsys/region.h"
#include "rsys/picture.h"
#include "sspairtable.c"
/*
* Basically a region is just a bunch of stop start pairs where the pairs
* are the starting and stopping points of xors off the previous line.
* As such, the meat of this loop is just to xor all the lines with their
* immediately preceeding lines and output those values. To start things
* off and to finish things we need to do an xor with a line of zeros, and
* we don't count on the bits past bounds.right necessarily containing zeros,
* so it is necessary to temporarily hold those characters, mask them off
* and then replace them after we've finished with the line.
*
* After we're done there's a chance that the region we constructed was
* either a null region or a simple rectangle, so we detect that and adjust
* by hand.
*
* NOTE: with our "special" regions, the maximum size a region can have
* is 32767, unlike what IMVI-17-25 states.
*/
#define MAXRGNSIZE 32767
P2 (PUBLIC pascal trap, OSErr, BitMapToRegion, RgnHandle, rh,
const BitMap *, bmp)
{
INTEGER top, left, bottom, right, rowbytes, linelen, rgnsize;
INTEGER x, y;
unsigned char scruffmask, scruffhold0, scruffhold1;
unsigned char *zeroline;
unsigned char *line0p, *line1p, c, *p, *saveline0p, *saveline1p;
INTEGER *outp, *endoutp, transition;
BOOLEAN havewritteny;
/* 0x00 or 0x100, depending on the state of the last xorred byte */
unsigned int tableindex;
if ((bmp->rowBytes & ~CWC(ROWMASK))
&& ((PixMap *)bmp)->pixelSize != CWC(1))
/*-->*/ return pixmapTooDeepErr;
SetHandleSize((Handle) rh, MAXRGNSIZE);
outp = (INTEGER *) ((char *) STARH(rh) + SMALLRGN);
endoutp = (INTEGER *) ((char *) STARH(rh) + MAXRGNSIZE);
#define OUTPUT(v) \
do \
{ \
if (outp >= endoutp) \
{ \
/* ### set the size to something reasonable, although we \
should see what the mac does */ \
SetHandleSize ((Handle) rh, SMALLRGN); \
return rgnTooBigErr; \
} \
else \
*outp++ = CW(v); \
} while (0)
top = CW(bmp->bounds.top);
left = CW(bmp->bounds.left);
bottom = CW(bmp->bounds.bottom);
right = CW(bmp->bounds.right);
rowbytes = CW(bmp->rowBytes) & ROWMASK;
linelen = (right - left + 7) / 8;
if (linelen <= 0)
/*-->*/ goto it_is_empty;
scruffmask = 0xFF << (8 - ((right - left) % 8));
if (!scruffmask)
scruffmask = 0xFF;
zeroline = alloca (linelen);
memset (zeroline, 0, linelen);
line0p = zeroline;
line1p = (unsigned char *) MR (bmp->baseAddr);
for (y = top; y <= bottom; ++y)
{
if (y == bottom)
line1p = zeroline;
saveline0p = line0p;
saveline1p = line1p;
scruffhold0 = line0p[linelen-1];
line0p[linelen-1] &= scruffmask;
scruffhold1 = line1p[linelen-1];
line1p[linelen-1] &= scruffmask;
tableindex = 0x0;
havewritteny = FALSE;
for (x = left - 1; x < left + linelen * 8 - 1; x += 8)
{
c = *line0p++ ^ *line1p++;
p = sspairtable[tableindex | c];
if (*p && !havewritteny)
{
OUTPUT(y);
havewritteny = TRUE;
}
while ((transition = *p++))
OUTPUT(x + transition);
tableindex = (c & 1) << 8;
}
if (tableindex)
OUTPUT (x + 1);
if (havewritteny)
OUTPUT(RGNSTOP);
saveline0p[linelen-1] = scruffhold0;
saveline1p[linelen-1] = scruffhold1;
line0p = saveline1p;
line1p = saveline1p + rowbytes;
}
OUTPUT(RGNSTOP);
rgnsize = (char *) outp - (char *) STARH(rh);
switch (rgnsize)
{
case SMALLRGN + sizeof(INTEGER):
it_is_empty:
RECT_ZERO (&RGN_BBOX (rh));
RGN_SET_SMALL (rh);
break;
case SMALLRGN + 9 * sizeof(INTEGER):
outp = RGN_DATA (rh);
HxX(rh, rgnBBox.top) = outp[0];
HxX(rh, rgnBBox.left) = outp[1];
HxX(rh, rgnBBox.bottom) = outp[4];
HxX(rh, rgnBBox.right) = outp[2];
RGN_SET_SMALL (rh);
break;
default:
HxX(rh, rgnBBox) = bmp->bounds;
/* #warning we are not setting the bounding box properly */
#if 1
HxX(rh, rgnSize) = CW(rgnsize);
#else
RGN_SET_SMALL (rh);
#endif
break;
}
SetHandleSize((Handle) rh, RGN_SIZE (rh));
return noErr;
}
P1 (PUBLIC pascal trap, PicHandle, OpenCPicture, OpenCPicParams *, newheaderp)
{
PicHandle retval;
retval = ROMlib_OpenPicture_helper (&newheaderp->srcRect, newheaderp);
return retval;
}