mirror of
https://github.com/ctm/executor.git
synced 2024-09-29 18:58:01 +00:00
168 lines
4.7 KiB
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;
|
||
|
}
|