💾 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 */
/*

	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 );
}