mirror of
https://github.com/elliotnunn/supermario.git
synced 2024-11-28 13:52:37 +00:00
643 lines
19 KiB
C
643 lines
19 KiB
C
|
/*
|
|||
|
File: puPixMaps.c
|
|||
|
|
|||
|
Contains: All the routines that work on pixMaps for the picture utilities package. There is one routine
|
|||
|
(DoCopyBits) that does things with pixMaps that is not in this file, but that is because it
|
|||
|
only extracts pixMaps out of a picture and then passes them to RecordPixMapGuts (in this file).
|
|||
|
|
|||
|
Written by: Dave Good. Some ideas stolen from Konstantin Othmer and Bruce Leak. Prototyped by Cris Rys.
|
|||
|
|
|||
|
Copyright: © 1990 by Apple Computer, Inc., all rights reserved.
|
|||
|
|
|||
|
This file is used in these builds: BigBang
|
|||
|
|
|||
|
Change History (most recent first):
|
|||
|
|
|||
|
<18> 2/21/91 SMC KON,#(to be announced): Fixed case of CLUT with less than
|
|||
|
2^pixelsize entries getting padded with too many extra colors
|
|||
|
and writing off the end of the buffer.
|
|||
|
<17> 2/14/91 SMC KON,#82895: Suppress black and white in ConvertBankTo555 so that
|
|||
|
colors near black or white don't show up later.
|
|||
|
<16> 2/6/91 SMC DDG,#81681: Fixed ConvertBankTo555 to reset the count of unique
|
|||
|
colors and to properly keep track of the number of pixels of a
|
|||
|
specified color (it used to “forget” about some of the pixels
|
|||
|
that corresponded to an index).
|
|||
|
<15> 2/4/91 SMC KON,#82191: Fixed the way pixmaps were getting colorized. The
|
|||
|
context of the fore and back colors was switched.
|
|||
|
<14> 1/16/91 dba (DDG) calculate a source rectangle in RecordPixMapInfo
|
|||
|
<13> 9/25/90 DDG Saved a few bytes throughout various routines.
|
|||
|
<12> 9/25/90 DDG Fixed a bug in “RecordPixMapGuts”, where the
|
|||
|
“MakeTrueColorTable” routine was being called with a bogus color
|
|||
|
table pointer in the case of bitMaps. Also fixed two bugs in the
|
|||
|
“MakeTrueColorTable” routine when it generates relative colors.
|
|||
|
The first one was that the dest pointer was not being set right
|
|||
|
when the relative color loop started. The second was that colors
|
|||
|
used to be able to wrap around to black, sometimes giving two
|
|||
|
instances of black in the color table. They are now clipped to
|
|||
|
white.
|
|||
|
<11> 9/21/90 DDG Made changes from code review. Moved several routines to
|
|||
|
assembly language (“puLowLevel.a”).
|
|||
|
<10> 8/5/90 DDG Fixed several bugs with recording custom colors.
|
|||
|
<9> 8/3/90 DDG Cleaned up the code some and added the CalcExactTable routine.
|
|||
|
<8> 8/2/90 DDG Added support for recording colors in custom color procs. Also
|
|||
|
incorporated Sean Callahan’s colorizing algorithm.
|
|||
|
<7> 8/1/90 DDG All sorts of changes to support relative entries in the pixmap’s
|
|||
|
color table.
|
|||
|
<6> 7/31/90 DDG Made RecordRGBColor respect the suppressBlackAndWhite verb.
|
|||
|
<5> 7/31/90 DDG Speeded up the suppressBlackAndWhite case for recording indexed
|
|||
|
pixMaps into exact color banks.
|
|||
|
<4> 7/30/90 DDG Added code to support the suppressBlackAndWhite verb. Also
|
|||
|
cleaned up the MakeIndexCache routine and the entire path thru
|
|||
|
adding colors to the color bank.
|
|||
|
<3> 7/30/90 DDG Added all sorts of routines to support exact color banks. Also
|
|||
|
fixed a bug in 32-bit pixMaps.
|
|||
|
<2> 7/29/90 DDG Fixed header.
|
|||
|
<1> 7/29/90 DDG First checked in using new structure.
|
|||
|
|
|||
|
To Do:
|
|||
|
*/
|
|||
|
|
|||
|
/*----------------------------------------------------------------------------------------------------------*/
|
|||
|
|
|||
|
/*
|
|||
|
| Includes
|
|||
|
*/
|
|||
|
|
|||
|
#include "puPrivate.h"
|
|||
|
#include <ToolUtils.h>
|
|||
|
|
|||
|
|
|||
|
/*----------------------------------------------------------------------------------------------------------*/
|
|||
|
|
|||
|
/*
|
|||
|
| Structures
|
|||
|
*/
|
|||
|
|
|||
|
typedef struct directPixel32 {
|
|||
|
|
|||
|
unsigned char filler;
|
|||
|
unsigned char red;
|
|||
|
unsigned char green;
|
|||
|
unsigned char blue;
|
|||
|
|
|||
|
} directPixel32, *directPixel32Ptr;
|
|||
|
|
|||
|
|
|||
|
|
|||
|
/*----------------------------------------------------------------------------------------------------------*/
|
|||
|
|
|||
|
/*
|
|||
|
| Declarations
|
|||
|
*/
|
|||
|
|
|||
|
void MakeIndexCache( InternalPictInfoPtr );
|
|||
|
void ConvertBankTo555( InternalPictInfoPtr );
|
|||
|
void MakeTrueColorTable( InternalPictInfoPtr, CTabHandle, short );
|
|||
|
|
|||
|
|
|||
|
|
|||
|
/*----------------------------------------------------------------------------------------------------------*/
|
|||
|
|
|||
|
|
|||
|
|
|||
|
/*----------------------------------------------------------------------------------------------------------*/
|
|||
|
/************************************************************************************************************/
|
|||
|
/**** Functions Follow ****/
|
|||
|
/************************************************************************************************************/
|
|||
|
/*----------------------------------------------------------------------------------------------------------*/
|
|||
|
|
|||
|
|
|||
|
|
|||
|
/*----------------------------------------------------------------------------------------------------------*/
|
|||
|
|
|||
|
pascal OSErr __RecordPixMapInfo(
|
|||
|
register PictInfoID thePictInfoID,
|
|||
|
PixMapHandle thePixMapHandle )
|
|||
|
{
|
|||
|
register InternalPictInfoPtr theInfoPtr;
|
|||
|
register PixMapPtr thePixMapPtr;
|
|||
|
register OSErr error;
|
|||
|
char oldInfoState;
|
|||
|
CGrafPtr thePortPtr;
|
|||
|
|
|||
|
/*
|
|||
|
| Save the locked state of the information handle, then move it high and lock it down. After this,
|
|||
|
| then check the version number of the picture information record to make sure that it is valid.
|
|||
|
*/
|
|||
|
|
|||
|
if( (theInfoPtr = DerefPictInfoID(thePictInfoID, &oldInfoState)) == 0 )
|
|||
|
return pictInfoIDErr;
|
|||
|
|
|||
|
/*
|
|||
|
| Increment the proper count in the structure, depending on whether the “PixMap” is really a
|
|||
|
| PixMap or a BitMap.
|
|||
|
*/
|
|||
|
|
|||
|
thePixMapPtr = *thePixMapHandle;
|
|||
|
|
|||
|
if( IsPixMap(thePixMapPtr->rowBytes) )
|
|||
|
{
|
|||
|
++theInfoPtr->ext.pixMapCount;
|
|||
|
theInfoPtr->ext.hRes = thePixMapPtr->hRes;
|
|||
|
theInfoPtr->ext.vRes = thePixMapPtr->vRes;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
++theInfoPtr->ext.bitMapCount;
|
|||
|
theInfoPtr->ext.hRes = 72 << 16;
|
|||
|
theInfoPtr->ext.vRes = 72 << 16;
|
|||
|
}
|
|||
|
theInfoPtr->ext.sourceRect.bottom = thePixMapPtr->bounds.bottom - thePixMapPtr->bounds.top;
|
|||
|
theInfoPtr->ext.sourceRect.right = thePixMapPtr->bounds.right - thePixMapPtr->bounds.left;
|
|||
|
theInfoPtr->ext.sourceRect.top = 0;
|
|||
|
theInfoPtr->ext.sourceRect.left = 0;
|
|||
|
|
|||
|
/*
|
|||
|
| Check the current port’s version. If the port is a color port, then set the foreground and background
|
|||
|
| colors to black and white respectively.
|
|||
|
*/
|
|||
|
|
|||
|
GetPort( (GrafPtr *)(&thePortPtr) );
|
|||
|
|
|||
|
if( theInfoPtr->verb & (returnPalette | returnColorTable) )
|
|||
|
{
|
|||
|
theInfoPtr->foreColor.red = theInfoPtr->foreColor.green = theInfoPtr->foreColor.blue = 0x0000;
|
|||
|
theInfoPtr->backColor.red = theInfoPtr->backColor.green = theInfoPtr->backColor.blue = 0xFFFF;
|
|||
|
|
|||
|
if( IsColorPort(thePortPtr->portVersion) )
|
|||
|
{
|
|||
|
theInfoPtr->foreColor = thePortPtr->rgbFgColor;
|
|||
|
theInfoPtr->backColor = thePortPtr->rgbBkColor;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/*
|
|||
|
| Now, call the main “guts” routine that records the real information for the pixMap
|
|||
|
*/
|
|||
|
|
|||
|
error = RecordPixMapGuts(theInfoPtr, thePixMapHandle);
|
|||
|
|
|||
|
/*
|
|||
|
| Restore the state of the PictInfoID and return an error if there is one.
|
|||
|
*/
|
|||
|
|
|||
|
returnError:
|
|||
|
|
|||
|
HSetState( (Handle)thePictInfoID, oldInfoState );
|
|||
|
return error;
|
|||
|
}
|
|||
|
|
|||
|
/*----------------------------------------------------------------------------------------------------------*/
|
|||
|
|
|||
|
OSErr RecordPixMapGuts(
|
|||
|
register InternalPictInfoPtr theInfoPtr,
|
|||
|
PixMapHandle thePixMapHandle )
|
|||
|
{
|
|||
|
register PixMapPtr thePixMapPtr;
|
|||
|
register short width, height;
|
|||
|
register unsigned short white = 0xFFFF;
|
|||
|
long theIndexTable[256];
|
|||
|
OSErr error = noErr;
|
|||
|
short thePixelSize;
|
|||
|
unsigned short rowBytes;
|
|||
|
Boolean isPixMap;
|
|||
|
char oldPMState, oldCTState;
|
|||
|
|
|||
|
/*
|
|||
|
| Lock down the pixMap handle after first moving it high.
|
|||
|
*/
|
|||
|
|
|||
|
oldPMState = HGetState( (Handle)thePixMapHandle );
|
|||
|
if( error = MemError() )
|
|||
|
return error;
|
|||
|
|
|||
|
MoveHHi( (Handle)thePixMapHandle );
|
|||
|
HLock( (Handle)thePixMapHandle );
|
|||
|
|
|||
|
thePixMapPtr = *thePixMapHandle;
|
|||
|
|
|||
|
/*
|
|||
|
| Set the “isPixMap” and “thePixelSize” variables and set the maximum depth field is the information handle.
|
|||
|
*/
|
|||
|
|
|||
|
thePixelSize = 1;
|
|||
|
if( isPixMap = IsPixMap(thePixMapPtr->rowBytes) )
|
|||
|
thePixelSize = thePixMapPtr->pixelSize;
|
|||
|
|
|||
|
if( thePixelSize > theInfoPtr->ext.depth )
|
|||
|
theInfoPtr->ext.depth = thePixelSize;
|
|||
|
|
|||
|
/*
|
|||
|
| Check to see if we are returning color information in any form. If we are not, then
|
|||
|
| exit.
|
|||
|
*/
|
|||
|
|
|||
|
if( !(theInfoPtr->verb & (returnPalette | returnColorTable)) )
|
|||
|
goto exit;
|
|||
|
|
|||
|
/*
|
|||
|
| Setup a the variables needed to loop thru each pixel
|
|||
|
*/
|
|||
|
|
|||
|
height = thePixMapPtr->bounds.bottom - thePixMapPtr->bounds.top;
|
|||
|
width = thePixMapPtr->bounds.right - thePixMapPtr->bounds.left;
|
|||
|
rowBytes = thePixMapPtr->rowBytes & 0x3FFF;
|
|||
|
|
|||
|
/*
|
|||
|
| If we have a pixMap, then lock down the color table after moving it high. Note that
|
|||
|
| direct pixMaps do not have a color table, so we don’t lock them down.
|
|||
|
*/
|
|||
|
|
|||
|
if( isPixMap && (thePixMapPtr->pmTable) )
|
|||
|
{
|
|||
|
oldCTState = HGetState( (Handle)(thePixMapPtr->pmTable) );
|
|||
|
if( error = MemError() )
|
|||
|
goto exit;
|
|||
|
|
|||
|
MoveHHi( (Handle)(thePixMapPtr->pmTable) );
|
|||
|
HLock( (Handle)(thePixMapPtr->pmTable) );
|
|||
|
}
|
|||
|
|
|||
|
/*
|
|||
|
| If the foreground color is white and the background color is black, then don’t colorize. Otherwise, colorize
|
|||
|
| each RGBColor, using the stored foreground and background color.
|
|||
|
*/
|
|||
|
|
|||
|
theInfoPtr->colorizing = true;
|
|||
|
if( (theInfoPtr->foreColor.red == 0x0000) && (theInfoPtr->foreColor.green == 0x0000) && (theInfoPtr->foreColor.blue == 0x0000) &&
|
|||
|
(theInfoPtr->backColor.red == white) && (theInfoPtr->backColor.green == white) && (theInfoPtr->backColor.blue == white) )
|
|||
|
{
|
|||
|
theInfoPtr->colorizing = false;
|
|||
|
}
|
|||
|
|
|||
|
/*
|
|||
|
| If the pixMap is indexed, then make an index cache that stores the offset into the histogram for each value
|
|||
|
| of the index. Then call an assembly routine that records all the pixels into the color bank.
|
|||
|
*/
|
|||
|
|
|||
|
if( thePixelSize <= 8 )
|
|||
|
{
|
|||
|
theInfoPtr->colorTableEntries = 1 << thePixelSize;
|
|||
|
theInfoPtr->indexCachePtr = theIndexTable;
|
|||
|
MakeTrueColorTable(theInfoPtr, ( (isPixMap) ? thePixMapPtr->pmTable : 0), thePixelSize);
|
|||
|
|
|||
|
MakeIndexCache(theInfoPtr);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
theInfoPtr->indexCachePtr = nil;
|
|||
|
ConvertBankTo555(theInfoPtr);
|
|||
|
}
|
|||
|
|
|||
|
RecordPixels(theInfoPtr, width, height, rowBytes, (long)(thePixMapPtr->baseAddr), thePixelSize);
|
|||
|
|
|||
|
theInfoPtr->indexCachePtr = nil;
|
|||
|
|
|||
|
if( (theInfoPtr->colorBankType == ColorBankIsCustom) && (theInfoPtr->colorBankIndex > 0) )
|
|||
|
{
|
|||
|
RecordColors( theInfoPtr->pickProcData, (RGBColor *)(theInfoPtr->colorBankBuffer.ptr), (long)(theInfoPtr->colorBankIndex), &(theInfoPtr->ext.uniqueColors), theInfoPtr->colorPickMethod );
|
|||
|
theInfoPtr->colorBankIndex = 0;
|
|||
|
}
|
|||
|
|
|||
|
/*
|
|||
|
| Restore the state of the locked handles and return the error.
|
|||
|
*/
|
|||
|
|
|||
|
if( isPixMap && (thePixMapPtr->pmTable) )
|
|||
|
HSetState( (Handle)thePixMapPtr->pmTable, oldCTState );
|
|||
|
|
|||
|
exit:
|
|||
|
HSetState( (Handle)thePixMapHandle, oldPMState );
|
|||
|
return error;
|
|||
|
}
|
|||
|
|
|||
|
/*----------------------------------------------------------------------------------------------------------*/
|
|||
|
|
|||
|
void ConvertBankTo555(
|
|||
|
register InternalPictInfoPtr theInfoPtr )
|
|||
|
{
|
|||
|
register short index;
|
|||
|
register ColorSpec *theColorPtr;
|
|||
|
register short *countPtr;
|
|||
|
ColorSpec *maxColorPtr;
|
|||
|
ColorSpec tempBuffer[maximumExactColors];
|
|||
|
|
|||
|
if( theInfoPtr->colorBankType == ColorBankIsExactAnd555 )
|
|||
|
{
|
|||
|
theInfoPtr->colorBankType = ColorBankIs555;
|
|||
|
|
|||
|
BlockMove( theInfoPtr->colorBankBuffer.ptr, (char *)tempBuffer, (sizeof(ColorSpec) * maximumExactColors) );
|
|||
|
ClearMemoryBytes( theInfoPtr->colorBankBuffer.ptr, HistogramTableSize );
|
|||
|
|
|||
|
theColorPtr = tempBuffer;
|
|||
|
maxColorPtr = theColorPtr + theInfoPtr->ext.uniqueColors;
|
|||
|
theInfoPtr->ext.uniqueColors = 0;
|
|||
|
while( theColorPtr < maxColorPtr )
|
|||
|
{
|
|||
|
index = (theColorPtr->rgb.red >> 1) & 0x7C00;
|
|||
|
index += (theColorPtr->rgb.green >> 6) & 0x03E0;
|
|||
|
index += (theColorPtr->rgb.blue >> 11);
|
|||
|
|
|||
|
countPtr = (short *)(theInfoPtr->colorBankBuffer.ptr) + index;
|
|||
|
if( *countPtr == 0 )
|
|||
|
theInfoPtr->ext.uniqueColors++;
|
|||
|
*countPtr += theColorPtr->value;
|
|||
|
|
|||
|
++theColorPtr;
|
|||
|
}
|
|||
|
if (theInfoPtr->verb & suppressBlackAndWhite) {
|
|||
|
countPtr = (short *)(theInfoPtr->colorBankBuffer.ptr);
|
|||
|
if (*countPtr != 0) {
|
|||
|
*countPtr = 0;
|
|||
|
theInfoPtr->ext.uniqueColors--;
|
|||
|
}
|
|||
|
countPtr += 32767;
|
|||
|
if (*countPtr != 0) {
|
|||
|
*countPtr = 0;
|
|||
|
theInfoPtr->ext.uniqueColors--;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/*----------------------------------------------------------------------------------------------------------*/
|
|||
|
|
|||
|
/*
|
|||
|
| Note that this routine will never be called with colorsRequested less than uniqueColors.
|
|||
|
*/
|
|||
|
|
|||
|
void CalcExactTable(
|
|||
|
register short colorsRequested,
|
|||
|
register short uniqueColors,
|
|||
|
register ColorSpec *colorBankPtr,
|
|||
|
register ColorSpec *resultPtr )
|
|||
|
{
|
|||
|
register short value = 0;
|
|||
|
|
|||
|
colorsRequested -= uniqueColors;
|
|||
|
|
|||
|
while( --uniqueColors >= 0 )
|
|||
|
{
|
|||
|
resultPtr->value = value++;
|
|||
|
resultPtr->rgb = colorBankPtr->rgb;
|
|||
|
|
|||
|
++colorBankPtr;
|
|||
|
++resultPtr;
|
|||
|
}
|
|||
|
|
|||
|
while( --colorsRequested >= 0 )
|
|||
|
{
|
|||
|
resultPtr->value = value++;
|
|||
|
resultPtr->rgb.red = 0;
|
|||
|
resultPtr->rgb.green = 0;
|
|||
|
resultPtr->rgb.blue = 0;
|
|||
|
|
|||
|
++resultPtr;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/*----------------------------------------------------------------------------------------------------------*/
|
|||
|
|
|||
|
|
|||
|
|
|||
|
/*----------------------------------------------------------------------------------------------------------*/
|
|||
|
/************************************************************************************************************/
|
|||
|
/**** Internal Functions Follow ****/
|
|||
|
/************************************************************************************************************/
|
|||
|
/*----------------------------------------------------------------------------------------------------------*/
|
|||
|
|
|||
|
|
|||
|
|
|||
|
/*----------------------------------------------------------------------------------------------------------*/
|
|||
|
|
|||
|
static void MakeTrueColorTable(
|
|||
|
register InternalPictInfoPtr theInfoPtr,
|
|||
|
CTabHandle theCTHandle,
|
|||
|
short thePixelSize )
|
|||
|
{
|
|||
|
ColorSpec *srcColorPtr;
|
|||
|
register ColorSpec *dstColorPtr;
|
|||
|
register short index;
|
|||
|
register short entryCount;
|
|||
|
register short colorCount = 0;
|
|||
|
short value = 0;
|
|||
|
RGBColor combo;
|
|||
|
CTabPtr theCTPtr;
|
|||
|
short relativeEntries;
|
|||
|
char oldCTState;
|
|||
|
|
|||
|
entryCount = 1 << thePixelSize;
|
|||
|
|
|||
|
dstColorPtr = (ColorSpec *)(theInfoPtr->colorTableBuffer.ptr);
|
|||
|
for(index = 0; index < entryCount; ++index)
|
|||
|
{
|
|||
|
dstColorPtr->value = -1;
|
|||
|
++dstColorPtr;
|
|||
|
}
|
|||
|
|
|||
|
if( theCTHandle )
|
|||
|
{
|
|||
|
oldCTState = HGetState( (Handle)theCTHandle );
|
|||
|
HLock( (Handle)theCTHandle );
|
|||
|
theCTPtr = *theCTHandle;
|
|||
|
|
|||
|
colorCount = theCTPtr->ctSize + 1;
|
|||
|
srcColorPtr = &(theCTPtr->ctTable);
|
|||
|
|
|||
|
combo.red = theInfoPtr->foreColor.red ^ theInfoPtr->backColor.red;
|
|||
|
combo.green = theInfoPtr->foreColor.green ^ theInfoPtr->backColor.green;
|
|||
|
combo.blue = theInfoPtr->foreColor.blue ^ theInfoPtr->backColor.blue;
|
|||
|
|
|||
|
while( colorCount-- )
|
|||
|
{
|
|||
|
/*
|
|||
|
| The index into the color table should default to the value in the ColorSpec. However, if the
|
|||
|
| color table flag word has it’s highest bit set, then we need to ignore the value field and
|
|||
|
| use a constantly incrementing index.
|
|||
|
*/
|
|||
|
|
|||
|
index = srcColorPtr->value;
|
|||
|
if( theCTPtr->ctFlags < 0 )
|
|||
|
index = value++;
|
|||
|
|
|||
|
dstColorPtr = (ColorSpec *)(theInfoPtr->colorTableBuffer.ptr);
|
|||
|
dstColorPtr += index;
|
|||
|
|
|||
|
dstColorPtr->value = 0;
|
|||
|
|
|||
|
if( theInfoPtr->colorizing )
|
|||
|
{
|
|||
|
dstColorPtr->rgb.red = (srcColorPtr->rgb.red & combo.red) ^ theInfoPtr->foreColor.red; /*<15>*/
|
|||
|
dstColorPtr->rgb.green = (srcColorPtr->rgb.green & combo.green) ^ theInfoPtr->foreColor.green; /*<15>*/
|
|||
|
dstColorPtr->rgb.blue = (srcColorPtr->rgb.blue & combo.blue) ^ theInfoPtr->foreColor.blue; /*<15>*/
|
|||
|
}
|
|||
|
else
|
|||
|
dstColorPtr->rgb = srcColorPtr->rgb;
|
|||
|
|
|||
|
++srcColorPtr;
|
|||
|
}
|
|||
|
|
|||
|
colorCount = theCTPtr->ctSize + 1;
|
|||
|
HSetState( (Handle)theCTHandle, oldCTState );
|
|||
|
}
|
|||
|
|
|||
|
if( colorCount < entryCount )
|
|||
|
{
|
|||
|
Fixed theRed, theGreen, theBlue;
|
|||
|
Fixed incRed, incGreen, incBlue;
|
|||
|
|
|||
|
relativeEntries = entryCount - colorCount;
|
|||
|
|
|||
|
theRed = theInfoPtr->backColor.red;
|
|||
|
incRed = theInfoPtr->foreColor.red - theRed;
|
|||
|
if( incRed < 0 )
|
|||
|
{
|
|||
|
theRed = theInfoPtr->foreColor.red;
|
|||
|
incRed = -incRed;
|
|||
|
}
|
|||
|
|
|||
|
theGreen = theInfoPtr->backColor.green;
|
|||
|
incGreen = theInfoPtr->foreColor.green - theGreen;
|
|||
|
if( incGreen < 0 )
|
|||
|
{
|
|||
|
theGreen = theInfoPtr->foreColor.green;
|
|||
|
incGreen = -incGreen;
|
|||
|
}
|
|||
|
|
|||
|
theBlue = theInfoPtr->backColor.blue;
|
|||
|
incBlue = theInfoPtr->foreColor.blue - theBlue;
|
|||
|
if( incBlue < 0 )
|
|||
|
{
|
|||
|
theBlue = theInfoPtr->foreColor.blue;
|
|||
|
incBlue = -incBlue;
|
|||
|
}
|
|||
|
|
|||
|
theRed = (theRed << 16) + 0x8000;
|
|||
|
theGreen = (theGreen << 16) + 0x8000;
|
|||
|
theBlue = (theBlue << 16) + 0x8000;
|
|||
|
|
|||
|
incRed = FixRatio( (short)incRed, relativeEntries );
|
|||
|
incGreen = FixRatio( (short)incGreen, relativeEntries );
|
|||
|
incBlue = FixRatio( (short)incBlue, relativeEntries );
|
|||
|
|
|||
|
dstColorPtr = (ColorSpec *)(theInfoPtr->colorTableBuffer.ptr);
|
|||
|
for(index = 0; index < relativeEntries; ++index) /* <18> relativeEntries was entryCount */
|
|||
|
{
|
|||
|
register unsigned long temp;
|
|||
|
|
|||
|
if( dstColorPtr->value )
|
|||
|
{
|
|||
|
dstColorPtr->rgb.red = theRed >> 16;
|
|||
|
dstColorPtr->rgb.green = theGreen >> 16;
|
|||
|
dstColorPtr->rgb.blue = theBlue >> 16;
|
|||
|
|
|||
|
temp = (unsigned long)theRed;
|
|||
|
theRed += incRed;
|
|||
|
if( (unsigned long)theRed < temp )
|
|||
|
theRed = 0xFFFF0000;
|
|||
|
|
|||
|
temp = (unsigned long)theGreen;
|
|||
|
theGreen += incGreen;
|
|||
|
if( (unsigned long)theGreen < temp )
|
|||
|
theGreen = 0xFFFF0000;
|
|||
|
|
|||
|
temp = (unsigned long)theBlue;
|
|||
|
theBlue += incBlue;
|
|||
|
if( (unsigned long)theBlue < temp )
|
|||
|
theBlue = 0xFFFF0000;
|
|||
|
}
|
|||
|
++dstColorPtr;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/*----------------------------------------------------------------------------------------------------------*/
|
|||
|
|
|||
|
void MakeIndexCache(
|
|||
|
register InternalPictInfoPtr theInfoPtr )
|
|||
|
{
|
|||
|
register ColorSpec *theColorPtr;
|
|||
|
register long *indexCachePtr;
|
|||
|
register unsigned short index;
|
|||
|
register short colorCount;
|
|||
|
register short exactBankFlag;
|
|||
|
register short customBankFlag;
|
|||
|
|
|||
|
/*
|
|||
|
| Setup the variables that we are going to need.
|
|||
|
*/
|
|||
|
|
|||
|
indexCachePtr = theInfoPtr->indexCachePtr;
|
|||
|
colorCount = theInfoPtr->colorTableEntries;
|
|||
|
theColorPtr = (ColorSpec *)(theInfoPtr->colorTableBuffer.ptr);
|
|||
|
|
|||
|
exactBankFlag = theInfoPtr->colorBankType == ColorBankIsExactAnd555;
|
|||
|
customBankFlag = theInfoPtr->colorBankType == ColorBankIsCustom;
|
|||
|
|
|||
|
/*
|
|||
|
| Loop thru the entire color table, making an entry in the index cache for each color.
|
|||
|
*/
|
|||
|
|
|||
|
while( colorCount-- )
|
|||
|
{
|
|||
|
if( (theInfoPtr->verb & suppressBlackAndWhite) &&
|
|||
|
(theColorPtr->rgb.red == theColorPtr->rgb.green) &&
|
|||
|
(theColorPtr->rgb.red == theColorPtr->rgb.blue) &&
|
|||
|
((theColorPtr->rgb.red == 0x0000) || (theColorPtr->rgb.red == 0xFFFF)) )
|
|||
|
{
|
|||
|
*(indexCachePtr++) = -2;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
if( exactBankFlag )
|
|||
|
{
|
|||
|
ColorSpec *colorBankPtr;
|
|||
|
|
|||
|
/*
|
|||
|
| If the color bank is an array of exact colors, then scan thru all these colors and see if any of them
|
|||
|
| match the color we are trying to cache. If there is already a color in the bank, then set the index
|
|||
|
| cache entry to the offset into the color bank of this color. Otherwise, set the cache entry to -1.
|
|||
|
*/
|
|||
|
|
|||
|
colorBankPtr = (ColorSpec *)(theInfoPtr->colorBankBuffer.ptr);
|
|||
|
|
|||
|
for(index = theInfoPtr->ext.uniqueColors; index > 0; index--)
|
|||
|
{
|
|||
|
if( colorBankPtr->rgb == theColorPtr->rgb )
|
|||
|
{
|
|||
|
*(indexCachePtr++) = (long)colorBankPtr - (long)(theInfoPtr->colorBankBuffer.ptr);
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
++colorBankPtr;
|
|||
|
}
|
|||
|
|
|||
|
if( index == 0 )
|
|||
|
*(indexCachePtr++) = -1;
|
|||
|
}
|
|||
|
else if( customBankFlag )
|
|||
|
{
|
|||
|
*(indexCachePtr++) = -3;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
/*
|
|||
|
| If the color bank is a 555 histogram, then calculate the index into the histogram for this color.
|
|||
|
| Then check to see if we are suppressing black and white, and if we are AND the color is black
|
|||
|
| or white, then set the index cache index to -2.
|
|||
|
*/
|
|||
|
|
|||
|
index = (theColorPtr->rgb.red >> 1) & 0x7C00;
|
|||
|
index += (theColorPtr->rgb.green >> 6) & 0x03E0;
|
|||
|
index += (theColorPtr->rgb.blue >> 11);
|
|||
|
|
|||
|
*(indexCachePtr++) = (unsigned long)(index) << 1;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
++theColorPtr;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/*----------------------------------------------------------------------------------------------------------*/
|