💾 Archived View for mirrors.apple2.org.za › archive › apple.cabi.net › Graphics › PICT.and_QT.INFO ›… captured on 2024-05-10 at 15:25:39.
View Raw
More Information
⬅️ Previous capture (2023-01-29)
-=-=-=-=-=-=-
/* Prototypes */
PicHandle CreatePICT2( PixMap *srcBits, Rect *srcRect, Rect *dstRect, short mode );
void PutOutPixMapSrcRectDstRectAndMode( PixMap *srcBits, short** inPicPtr, Rect *srcRect, Rect *dstRect, short mode );
long PutOutPackedIndexedPixData( PixMap *srcBits, short **picPtr );
long PutOutPackedDirectPixData( PixMap *srcBits, short **picPtr );
PicHandle
CreatePICT2(PixMap *srcBits, Rect *srcRect, Rect *dstRect,
short mode)
{
PicHandle myPic;
short myRowBytes;
short *picPtr;
short iii;
long handleSize;
#define CLIPSIZE 12
#define PIXMAPRECSIZE 50
#define HEADERSIZE 40
#define MAXCOLORTABLESIZE 256*8+8
#define OPCODEMISCSIZE 2+8+8+2 /* opcode+srcRect+dstRect+mode */
#define ENDOFPICTSIZE 2
#define PICSIZE PIXMAPRECSIZE + HEADERSIZE + MAXCOLORTABLESIZE +\
ENDOFPICTSIZE + OPCODEMISCSIZE + CLIPSIZE
myRowBytes = srcBits->rowBytes & 0x3fff;
/* Allocate worst-case memory scenario using PackBits packing. */
myPic = (PicHandle) NewHandle( PICSIZE +
(long)((myRowBytes/127)+2+myRowBytes)*(long)(srcBits->bounds.bottom
- srcBits->bounds.top));
if(!myPic)
return(0);
/* Skip picSize and put out picFrame (10 bytes). */
picPtr = (short *) (((long)*myPic) + 2);
*picPtr++ = dstRect->top;
*picPtr++ = dstRect->left;
*picPtr++ = dstRect->bottom;
*picPtr++ = dstRect->right;
/* Put out header (30 bytes). This could be done from a resource or
taken from an existing picture. */
*picPtr++ = 0x11; /* Version opcode. */
*picPtr++ = 0x2ff; /* Version number. */
*picPtr++ = 0xC00; /* Header opcode. */
*picPtr++ = 0xFFFF; /* Put out PICT header version. */
*picPtr++ = 0xFFFF;
/* The rest of the header is ignored--0 it out. */
for(iii = 10; iii > 0; iii--)
*picPtr++ = 0; /* Write out 24 bytes of 0. */
/* Put out current port's clip region. */
*picPtr++ = 0x01;
*picPtr++ = 0x0A; /* Clip region only has bounds rectangle. */
*picPtr++ = (**thePort->clipRgn).rgnBBox.top;
*picPtr++ = (**thePort->clipRgn).rgnBBox.left;
*picPtr++ = (**thePort->clipRgn).rgnBBox.bottom;
*picPtr++ = (**thePort->clipRgn).rgnBBox.right;
HLock(myPic);
if(srcBits->pixelType == RGBDirect)
{ /* Must be 32-bits/pixel */
/* Put out opCode $9A, DirectBitsRect. */
*picPtr++ = 0x9A;
*picPtr++ = 0; /* BaseAddr for direct pixMaps is 0x000000FF. */
*picPtr++ = 0xFF;
PutOutPixMapSrcRectDstRectAndMode(srcBits, &picPtr, srcRect,
dstRect, mode);
if(PutOutPackedDirectPixData(srcBits, &picPtr)) /* Nonzero
indicates an error. */
goto errorExit;
}
else
{
/* Put out opCode $98, PackBitsRect. */
*picPtr++ = 0x98;
PutOutPixMapSrcRectDstRectAndMode(srcBits, &picPtr, srcRect,
dstRect, mode);
if(PutOutPackedIndexedPixData(srcBits, &picPtr)) /* Nonzero
indicates an error. */
goto errorExit;
}
HUnlock(myPic);
/* All done! Put out end-of-picture opcode, $00FF. */
*picPtr++ = 0x00FF;
/* Size handle down to the amount actually used. */
handleSize = (long) picPtr - (long) *myPic;
SetHandleSize( myPic, handleSize );
/* Write out picture size. */
*((short *)*myPic) = (short) handleSize;
return(myPic);
errorExit:
DisposHandle(myPic);
return(0);
}
void
PutOutPixMapSrcRectDstRectAndMode( PixMap *srcBits, short** inPicPtr, Rect *srcRect,
Rect *dstRect, short mode )
{
short iii;
short * picPtr = *inPicPtr;
short myRowBytes = srcBits->rowBytes & 0x3fff;
/* put out pixMap */
*picPtr++ = srcBits->rowBytes | 0x8000; /*always make PixMaps */
*picPtr++ = srcBits->bounds.top; /* Bounds */
*picPtr++ = srcBits->bounds.left;
*picPtr++ = srcBits->bounds.bottom;
*picPtr++ = srcBits->bounds.right;
*picPtr++ = 0; /* version number */
/*
- * Put out packing format:
- * 0 is default indexed packing.
- * 1 is no packing (rowBytes < 8 )
- * 4 is default direct packing - run length encoded scan lines by component, red first.
- /
if( myRowBytes < 8 && myRowBytes > 0 )
*picPtr++ = 1; /* packing format: unpacked */
else
{
if( srcBits->pixelType == RGBDirect )
*picPtr++ = 4;
else
*picPtr++ = 0; /* packing format: standard */
}
*picPtr++ = 0; /* packed size */
*picPtr++ = 0;
*picPtr++ = 0x48; /* horizontal resolution: $0048 0000 */
*picPtr++ = 0;
*picPtr++ = 0x48; /* vertical resolution: $0048 0000 */
*picPtr++ = 0;
/* these fields are different for BitMap/PixMap */
if( srcBits->rowBytes < 0 )
{/* do PixMap */
*picPtr++ = srcBits->pixelType;
*picPtr++ = srcBits->pixelSize; /* pixel size */
*picPtr++ = srcBits->cmpCount; /* number of components */
*picPtr++ = srcBits->cmpSize; /* size of each component */
}
else
{/* do BitMap */
*picPtr++ = 0;
*picPtr++ = 1; /* pixel size */
*picPtr++ = 1; /* number of components */
*picPtr++ = 1; /* size of each component */
}
*picPtr++ = 0; /* offset to next plane */
*picPtr++ = 0;
if( srcBits->pixelType == RGBDirect )
{
*picPtr++ = 0; /* color table is nil for Direct pixmaps*/
*picPtr++ = 0;
}
else
{
*picPtr++ = (unsigned short) srcBits->pmTable>>16; /* color table */
*picPtr++ = (unsigned short) srcBits->pmTable;
}
*picPtr++ = 0; /* reserved */
*picPtr++ = 0;
/* put out colortable if indexed pixmap*/
if( (srcBits->rowBytes < 0) && (srcBits->pmTable) && (srcBits->pixelType != RGBDirect) )
{
short* ctPtr = (short *) *(srcBits->pmTable); /* Get ptr to color table */
*picPtr++ = *ctPtr++; /* copy ctSeed */
*picPtr++ = *ctPtr++;
*picPtr++ = *ctPtr++; /* copy ctFlags */
iii = *ctPtr;
*picPtr++ = *ctPtr++; /* copy ctSize */
for( ; iii >= 0; iii-- )
{/* put out all entries */
*picPtr++ = *ctPtr++; /* pixel value */
*picPtr++ = *ctPtr++; /* red */
*picPtr++ = *ctPtr++; /* green */
*picPtr++ = *ctPtr++; /* blue */
}
}
else
if( srcBits->pixelType != RGBDirect )
{
for( iii = 8; iii > 0; iii-- )
*picPtr++ = 0; /* put out an empty color table: 8 words of 0 */
}
/* put out srcrect, dstrect, and mode */
*picPtr++ = srcRect->top;
*picPtr++ = srcRect->left;
*picPtr++ = srcRect->bottom;
*picPtr++ = srcRect->right;
*picPtr++ = dstRect->top;
*picPtr++ = dstRect->left;
*picPtr++ = dstRect->bottom;
*picPtr++ = dstRect->right;
*picPtr++ = mode;
*inPicPtr = picPtr;
}
long
PutOutPackedIndexedPixData( PixMap *srcBits, short **picPtr )
{
Ptr srcPtr = srcBits->baseAddr;
Ptr dstPtr;
Ptr packBuf;
Ptr tempPicPtr = (char*) *picPtr;
short packedSize;
short iii, jjj;
unsigned short myRowBytes;
myRowBytes = srcBits->rowBytes & 0x3fff;
/* put out PixData */
if( myRowBytes < 8 )
{ /* no packing */
short * pixMapPtr = (short *) srcBits->baseAddr;
for( iii = (myRowBytes*(srcBits->bounds.bottom - srcBits->bounds.top))/2; iii > 0; iii-- )
*tempPicPtr++ = *pixMapPtr++;
return( 0 );
}
packBuf = (Ptr)NewPtr( myRowBytes * 2 );
if( !packBuf )
return( -1 );
/* Must use only byte accesses to avoid address errors on 68K class machines */
for( iii = srcBits->bounds.bottom - srcBits->bounds.top; iii > 0; iii-- )
{
dstPtr = packBuf;
PackBits( &srcPtr, &dstPtr, myRowBytes );
packedSize = (long)dstPtr - (long)packBuf;
if( myRowBytes <= 250 )
{ /* put a byte to the picture */
*tempPicPtr++ = (unsigned char)packedSize;
}
else
{ /* put a word to the picture */
*tempPicPtr++ = (unsigned char)(packedSize>>8);
*tempPicPtr++ = (unsigned char)packedSize;
}
/* put the packed data out */
dstPtr = packBuf;
for( jjj = packedSize; jjj > 0; jjj-- )
{
*tempPicPtr++ = *dstPtr++;
}
}
DisposPtr( packBuf );
if( (long)tempPicPtr & (long)0x0001 ) /* do long alignment */
tempPicPtr++;
*picPtr = (short *) tempPicPtr;
return( 0 );
}
long
PutOutPackedDirectPixData( PixMap *srcBits, short **picPtr )
{
Ptr srcPtr;
Ptr dstPtr;
Ptr packBuf;
Ptr srcBuf;
Ptr srcBufPtr;
Ptr tempPicPtr = (char*) *picPtr;
short packedSize;
short iii, jjj, kkk;
unsigned short myRowBytes = srcBits->rowBytes & 0x3fff;
unsigned short componentRowBytes = myRowBytes>>2;
/* put out PixData */
if( myRowBytes < 8 )
{ /* no packing */
short * pixMapPtr = (short *) srcBits->baseAddr;
for( iii = (myRowBytes*(srcBits->bounds.bottom - srcBits->bounds.top))/2; iii > 0; iii-- )
*tempPicPtr++ = *pixMapPtr++;
return( 0 );
}
packBuf = (Ptr)NewPtr( myRowBytes * 2 );
if( !packBuf )
return( -1 );
/* allocate a buffer for separating the components */
srcBuf = (Ptr)NewPtr( componentRowBytes*3 );
if( !srcBuf )
return( -1 );
/* Must use only byte accesses to avoid address errors on 68K class machines */
for( iii = 0; iii < srcBits->bounds.bottom - srcBits->bounds.top; iii++ )
{
srcBufPtr = srcBuf;
for( jjj = 1; jjj <= 3; jjj++ ) /* Do red, green, and blue */
{
srcPtr = srcBits->baseAddr + (unsigned long)myRowBytes * iii;
srcPtr += jjj; /*point to this component */
for( kkk = 0; kkk < componentRowBytes; kkk++ )
{
*srcBufPtr++ = *srcPtr;
srcPtr += 4;
}
}
dstPtr = packBuf;
srcBufPtr = srcBuf;
PackBits( &srcBufPtr, &dstPtr, componentRowBytes*3 );
packedSize = (long)dstPtr - (long)packBuf;
if( myRowBytes <= 250 )
{ /* put a byte to the picture */
*tempPicPtr++ = (unsigned char)packedSize;
}
else
{ /* put a word to the picture */
*tempPicPtr++ = (unsigned char)(packedSize>>8);
*tempPicPtr++ = (unsigned char)packedSize;
}
/* put the packed data out */
dstPtr = packBuf;
for( kkk = packedSize; kkk > 0; kkk-- )
{
*tempPicPtr++ = *dstPtr++;
}
}
DisposPtr( packBuf );
DisposPtr( srcBuf );
if( (long)tempPicPtr & (long)0x0001 ) /* do long alignment */
tempPicPtr++;
*picPtr = (short *) tempPicPtr;
return( 0 );
}