1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015 |
- #ifdef JA2_PRECOMPILED_HEADERS
- #include "JA2 SGP ALL.H"
- #elif defined( WIZ8_PRECOMPILED_HEADERS )
- #include "WIZ8 SGP ALL.H"
- #else
- #include <math.h>
- #include <stdlib.h>
- #include "types.h"
- #include "string.h"
- #include "debug.h"
- #include "fileman.h"
- #include "himage.h"
- #include "impTGA.h"
- #include "pcx.h"
- #include "STCI.h"
- #include "wcheck.h"
- #include "Compression.h"
- #include "vobject.h"
- #endif
- // This is the color substituted to keep a 24bpp -> 16bpp color
- // from going transparent (0x0000) -- DB
- #define BLACK_SUBSTITUTE 0x0001
- UINT16 gusAlphaMask = 0;
- UINT16 gusRedMask = 0;
- UINT16 gusGreenMask = 0;
- UINT16 gusBlueMask = 0;
- INT16 gusRedShift = 0;
- INT16 gusBlueShift = 0;
- INT16 gusGreenShift = 0;
- // this funky union is used for fast 16-bit pixel format conversions
- typedef union
- {
- struct
- {
- UINT16 usLower;
- UINT16 usHigher;
- };
- UINT32 uiValue;
- } SplitUINT32;
- HIMAGE CreateImage( SGPFILENAME ImageFile, UINT16 fContents )
- {
- HIMAGE hImage = NULL;
- SGPFILENAME Extension;
- CHAR8 ExtensionSep[] = ".";
- STR StrPtr;
- UINT32 iFileLoader;
- // Depending on extension of filename, use different image readers
- // Get extension
- StrPtr = strstr( ImageFile, ExtensionSep );
- if ( StrPtr == NULL )
- {
- // No extension given, use default internal loader extension
- DbgMessage( TOPIC_HIMAGE, DBG_LEVEL_2, "No extension given, using default" );
- strcat( ImageFile, ".PCX" );
- strcpy( Extension, ".PCX" );
- }
- else
- {
- strcpy( Extension, StrPtr+1 );
- }
- // Determine type from Extension
- do
- {
- iFileLoader = UNKNOWN_FILE_READER;
-
- if ( _stricmp( Extension, "PCX" ) == 0 )
- {
- iFileLoader = PCX_FILE_READER;
- break;
- }
- if ( _stricmp( Extension, "TGA" ) == 0 )
- {
- iFileLoader = TGA_FILE_READER;
- break;
- }
- if ( _stricmp( Extension, "STI" ) == 0 )
- {
- iFileLoader = STCI_FILE_READER;
- break;
- }
- } while ( FALSE );
- // Determine if resource exists before creating image structure
- if ( !FileExists( ImageFile ) )
- {
- //If in debig, make fatal!
- #ifdef JA2
- #ifdef _DEBUG
- //FatalError( "Resource file %s does not exist.", ImageFile );
- #endif
- #endif
- DbgMessage( TOPIC_HIMAGE, DBG_LEVEL_2, String("Resource file %s does not exist.", ImageFile) );
- return( NULL );
- }
- // Create memory for image structure
- hImage = (HIMAGE)MemAlloc( sizeof( image_type ) );
- AssertMsg( hImage, "Failed to allocate memory for hImage in CreateImage");
- // Initialize some values
- memset( hImage, 0, sizeof( image_type ) );
-
- //hImage->fFlags = 0;
- // Set data pointers to NULL
- //hImage->pImageData = NULL;
- //hImage->pPalette = NULL;
- //hImage->pui16BPPPalette = NULL;
- // Set filename and loader
- strcpy( hImage->ImageFile, ImageFile );
- hImage->iFileLoader = iFileLoader;
- if ( !LoadImageData( hImage, fContents ) )
- {
- return( NULL );
- }
- // All is fine, image is loaded and allocated, return pointer
- return( hImage );
- }
- BOOLEAN DestroyImage( HIMAGE hImage )
- {
- Assert( hImage != NULL );
- // First delete contents
- ReleaseImageData( hImage, IMAGE_ALLDATA );//hImage->fFlags );
- // Now free structure
- MemFree( hImage );
- return( TRUE );
- }
- BOOLEAN ReleaseImageData( HIMAGE hImage, UINT16 fContents )
- {
- Assert( hImage != NULL );
-
- if ( (fContents & IMAGE_PALETTE) && (hImage->fFlags & IMAGE_PALETTE) )
- {
- //Destroy palette
- if( hImage->pPalette != NULL )
- {
- MemFree( hImage->pPalette );
- hImage->pPalette = NULL;
- }
- if ( hImage->pui16BPPPalette != NULL )
- {
- MemFree( hImage->pui16BPPPalette );
- hImage->pui16BPPPalette = NULL;
- }
- // Remove contents flag
- hImage->fFlags = hImage->fFlags ^ IMAGE_PALETTE;
- }
-
- if ( (fContents & IMAGE_BITMAPDATA) && (hImage->fFlags & IMAGE_BITMAPDATA) )
- {
- //Destroy image data
- Assert( hImage->pImageData != NULL );
- MemFree( hImage->pImageData );
- hImage->pImageData = NULL;
- if (hImage->usNumberOfObjects > 0)
- {
- MemFree( hImage->pETRLEObject );
- }
- // Remove contents flag
- hImage->fFlags = hImage->fFlags ^ IMAGE_BITMAPDATA;
- }
- if ( (fContents & IMAGE_APPDATA) && (hImage->fFlags & IMAGE_APPDATA) )
- {
- // get rid of the APP DATA
- if ( hImage->pAppData != NULL )
- {
- MemFree( hImage->pAppData );
- hImage->fFlags &= (~IMAGE_APPDATA);
- }
- }
- return( TRUE );
- }
- BOOLEAN LoadImageData( HIMAGE hImage, UINT16 fContents )
- {
- BOOLEAN fReturnVal = FALSE;
- Assert( hImage != NULL );
- // Switch on file loader
- switch( hImage->iFileLoader )
- {
- case TGA_FILE_READER:
- fReturnVal = LoadTGAFileToImage( hImage, fContents );
- break;
- case PCX_FILE_READER:
- fReturnVal = LoadPCXFileToImage( hImage, fContents );
- break;
- case STCI_FILE_READER:
- fReturnVal = LoadSTCIFileToImage( hImage, fContents );
- break;
- default:
- DbgMessage( TOPIC_HIMAGE, DBG_LEVEL_2, "Unknown image loader was specified." );
- }
-
- if ( !fReturnVal )
- {
- DbgMessage( TOPIC_HIMAGE, DBG_LEVEL_2, "Error occured while reading image data." );
- }
- return( fReturnVal );
- }
- BOOLEAN CopyImageToBuffer( HIMAGE hImage, UINT32 fBufferType, BYTE *pDestBuf, UINT16 usDestWidth, UINT16 usDestHeight, UINT16 usX, UINT16 usY, SGPRect *srcRect )
- {
- // Use blitter based on type of image
- Assert( hImage != NULL );
- if ( hImage->ubBitDepth == 8 && fBufferType == BUFFER_8BPP )
- {
- #ifndef NO_ZLIB_COMPRESSION
- if ( hImage->fFlags & IMAGE_COMPRESSED )
- {
- DbgMessage( TOPIC_HIMAGE, DBG_LEVEL_2, "Copying Compressed 8 BPP Imagery." );
- return( Copy8BPPCompressedImageTo8BPPBuffer( hImage, pDestBuf, usDestWidth, usDestHeight, usX, usY, srcRect ) );
- }
- #endif
- // Default do here
- DbgMessage( TOPIC_HIMAGE, DBG_LEVEL_2, "Copying 8 BPP Imagery." );
- return ( Copy8BPPImageTo8BPPBuffer( hImage, pDestBuf, usDestWidth, usDestHeight, usX, usY, srcRect ) );
- }
- if ( hImage->ubBitDepth == 8 && fBufferType == BUFFER_16BPP )
- {
- #ifndef NO_ZLIB_COMPRESSION
- if ( hImage->fFlags & IMAGE_COMPRESSED )
- {
- DbgMessage( TOPIC_HIMAGE, DBG_LEVEL_3, "Copying Compressed 8 BPP Imagery to 16BPP Buffer." );
- return ( Copy8BPPCompressedImageTo16BPPBuffer( hImage, pDestBuf, usDestWidth, usDestHeight, usX, usY, srcRect ) );
- }
- #endif
- // Default do here
- DbgMessage( TOPIC_HIMAGE, DBG_LEVEL_3, "Copying 8 BPP Imagery to 16BPP Buffer." );
- return ( Copy8BPPImageTo16BPPBuffer( hImage, pDestBuf, usDestWidth, usDestHeight, usX, usY, srcRect ) );
- }
- if ( hImage->ubBitDepth == 16 && fBufferType == BUFFER_16BPP )
- {
- #ifndef NO_ZLIB_COMPRESSION
- if ( hImage->fFlags & IMAGE_COMPRESSED )
- {
- DbgMessage( TOPIC_HIMAGE, DBG_LEVEL_3, "Automatically Copying Compressed 16 BPP Imagery." );
- return( Copy16BPPCompressedImageTo16BPPBuffer( hImage, pDestBuf, usDestWidth, usDestHeight, usX, usY, srcRect ) );
- }
- #endif
- DbgMessage( TOPIC_HIMAGE, DBG_LEVEL_3, "Automatically Copying 16 BPP Imagery." );
- return( Copy16BPPImageTo16BPPBuffer( hImage, pDestBuf, usDestWidth, usDestHeight, usX, usY, srcRect ) );
- }
- return( FALSE );
- }
- #ifndef NO_ZLIB_COMPRESSION
- BOOLEAN Copy8BPPCompressedImageTo8BPPBuffer( HIMAGE hImage, BYTE *pDestBuf, UINT16 usDestWidth, UINT16 usDestHeight, UINT16 usX, UINT16 usY, SGPRect *srcRect )
- {
- UINT32 uiNumLines;
- UINT32 uiLineSize;
- UINT32 uiCnt;
- UINT8 * pDest;
- UINT32 uiDestStart;
-
- UINT8 * pScanLine;
- PTR pDecompPtr;
- UINT32 uiDecompressed;
- // Assertions
- Assert( hImage != NULL );
- Assert( hImage->pCompressedImageData != NULL );
- // Validations
- CHECKF( usX >= 0 );
- CHECKF( usX < usDestWidth );
- CHECKF( usY >= 0 );
- CHECKF( usY < usDestHeight );
- CHECKF( srcRect->iRight > srcRect->iLeft );
- CHECKF( srcRect->iBottom > srcRect->iTop );
- DbgMessage( TOPIC_HIMAGE, DBG_LEVEL_3, "8BPP to 8BPP Compressed Blitter Called!" );
- // determine where to start Copying and rectangle size
- uiDestStart = usY * usDestWidth + usX;
- uiNumLines = srcRect->iBottom - srcRect->iTop;
- uiLineSize = srcRect->iRight - srcRect->iLeft;
- Assert( usDestWidth >= uiLineSize );
- Assert( usDestHeight >= uiNumLines );
- pDest = (UINT8 *) pDestBuf + uiDestStart;
- // Copying a portion of a compressed image is rather messy
- // because we have to decompress past all the data we want
- // to skip.
- // To keep memory requirements small and regular, we will
- // decompress one scanline at a time even if none of the data will
- // be blitted (but stop when the bottom line of the rectangle
- // to blit has been done).
- // initialize the decompression routines
- pDecompPtr = DecompressInit( hImage->pCompressedImageData, hImage->usWidth * hImage->usHeight );
- CHECKF( pDecompPtr );
- // Allocate memory for one scanline
- pScanLine = MemAlloc( hImage->usWidth );
- CHECKF( pScanLine );
- // go past all the scanlines we don't need to process
- for (uiCnt = 0; uiCnt < (UINT32) srcRect->iTop; uiCnt++)
- {
- uiDecompressed = Decompress( pDecompPtr, pScanLine, hImage->usWidth );
- Assert( uiDecompressed == hImage->usWidth );
- }
- // now we start Copying
- for (uiCnt = 0; uiCnt < uiNumLines - 1; uiCnt++)
- {
- // decompress a scanline
- uiDecompressed = Decompress( pDecompPtr, pScanLine, hImage->usWidth );
- Assert( uiDecompressed == hImage->usWidth );
- // and blit
- // memcpy( pDest, pScanLine + srcRect->iLeft, uiLineSize );
- pDest += usDestWidth;
- }
- // decompress the last scanline and blit
- uiDecompressed = Decompress( pDecompPtr, pScanLine, hImage->usWidth );
- Assert( uiDecompressed == hImage->usWidth );
- // memcpy( pDest, pScanLine + srcRect->iLeft, uiLineSize );
- DecompressFini( pDecompPtr );
- return( TRUE );
- }
- BOOLEAN Copy8BPPCompressedImageTo16BPPBuffer( HIMAGE hImage, BYTE *pDestBuf, UINT16 usDestWidth, UINT16 usDestHeight, UINT16 usX, UINT16 usY, SGPRect *srcRect )
- {
- UINT32 uiNumLines;
- UINT32 uiLineSize;
- UINT32 uiLine;
- UINT32 uiCol;
- UINT16 * pDest;
- UINT16 * pDestTemp;
- UINT32 uiDestStart;
-
- UINT8 * pScanLine;
- UINT8 * pScanLineTemp;
- PTR pDecompPtr;
- UINT32 uiDecompressed;
- UINT16 * p16BPPPalette;
- // Assertions
- Assert( hImage != NULL );
- Assert( hImage->pCompressedImageData != NULL );
- DbgMessage( TOPIC_HIMAGE, DBG_LEVEL_3, "Start check" );
- // Validations
- CHECKF( usX >= 0 );
- CHECKF( usX < usDestWidth );
- CHECKF( usY >= 0 );
- CHECKF( usY < usDestHeight );
- CHECKF( srcRect->iRight > srcRect->iLeft );
- CHECKF( srcRect->iBottom > srcRect->iTop );
- DbgMessage( TOPIC_HIMAGE, DBG_LEVEL_3, "End check" );
- p16BPPPalette = hImage->pui16BPPPalette;
- // determine where to start Copying and rectangle size
- uiDestStart = usY * usDestWidth + usX;
- uiNumLines = srcRect->iBottom - srcRect->iTop;
- uiLineSize = srcRect->iRight - srcRect->iLeft;
- Assert( usDestWidth >= uiLineSize );
- Assert( usDestHeight >= uiNumLines );
- pDest = (UINT16 *) pDestBuf;
- pDest += uiDestStart;
- DbgMessage( TOPIC_HIMAGE, DBG_LEVEL_3, String( "Start Copying at %p", pDest ) );
- // Copying a portion of a compressed image is rather messy
- // because we have to decompress past all the data we want
- // to skip.
- // To keep memory requirements small and regular, we will
- // decompress one scanline at a time even if none of the data will
- // be blitted (but stop when the bottom line of the rectangle
- // to blit has been done).
- // initialize the decompression routines
- pDecompPtr = DecompressInit( hImage->pCompressedImageData, hImage->usWidth * hImage->usHeight );
- CHECKF( pDecompPtr );
- // Allocate memory for one scanline
- pScanLine = MemAlloc( hImage->usWidth );
- CHECKF( pScanLine );
- // go past all the scanlines we don't need to process
- for (uiLine = 0; uiLine < (UINT32) srcRect->iTop; uiLine++)
- {
- DbgMessage( TOPIC_HIMAGE, DBG_LEVEL_3, "Skipping scanline" );
- uiDecompressed = Decompress( pDecompPtr, pScanLine, hImage->usWidth );
- Assert( uiDecompressed == hImage->usWidth );
- }
- DbgMessage( TOPIC_HIMAGE, DBG_LEVEL_3, "Actually Copying" );
- // now we start Copying
- for (uiLine = 0; uiLine < uiNumLines - 1; uiLine++)
- {
- // decompress a scanline
- uiDecompressed = Decompress( pDecompPtr, pScanLine, hImage->usWidth );
- Assert( uiDecompressed == hImage->usWidth );
-
- // set pointers and blit
- pDestTemp = pDest;
- pScanLineTemp = pScanLine + srcRect->iLeft;
- for (uiCol = 0; uiCol < uiLineSize; uiCol++ )
- {
- *pDestTemp = p16BPPPalette[ *pScanLineTemp ];
- pDestTemp++;
- pScanLineTemp++;
- }
- pDest += usDestWidth;
- }
-
- DbgMessage( TOPIC_HIMAGE, DBG_LEVEL_3, String( "End Copying at %p", pDest ) );
-
- DecompressFini( pDecompPtr );
- return( TRUE );
- }
- BOOLEAN Copy16BPPCompressedImageTo16BPPBuffer( HIMAGE hImage, BYTE *pDestBuf, UINT16 usDestWidth, UINT16 usDestHeight, UINT16 usX, UINT16 usY, SGPRect *srcRect )
- {
- // 16BPP Compressed image has not been implemented yet
- DbgMessage( TOPIC_HIMAGE, DBG_LEVEL_2, "16BPP Compressed imagery blitter has not been implemented yet." );
- return( FALSE );
- }
- #endif //NO_ZLIB_COMPRESSION
- BOOLEAN Copy8BPPImageTo8BPPBuffer( HIMAGE hImage, BYTE *pDestBuf, UINT16 usDestWidth, UINT16 usDestHeight, UINT16 usX, UINT16 usY, SGPRect *srcRect )
- {
- UINT32 uiSrcStart, uiDestStart, uiNumLines, uiLineSize;
- UINT32 cnt;
- UINT8 *pDest, *pSrc;
- // Assertions
- Assert( hImage != NULL );
- Assert( hImage->p16BPPData != NULL );
- // Validations
- CHECKF( usX >= 0 );
- CHECKF( usX < usDestWidth );
- CHECKF( usY >= 0 );
- CHECKF( usY < usDestHeight );
- CHECKF( srcRect->iRight > srcRect->iLeft );
- CHECKF( srcRect->iBottom > srcRect->iTop );
- // Determine memcopy coordinates
- uiSrcStart = srcRect->iTop * hImage->usWidth + srcRect->iLeft;
- uiDestStart = usY * usDestWidth + usX;
- uiNumLines = ( srcRect->iBottom - srcRect->iTop ) + 1;
- uiLineSize = ( srcRect->iRight - srcRect->iLeft ) + 1;
- Assert( usDestWidth >= uiLineSize );
- Assert( usDestHeight >= uiNumLines );
-
- // Copy line by line
- pDest = ( UINT8*)pDestBuf + uiDestStart;
- pSrc = hImage->p8BPPData + uiSrcStart;
- for( cnt = 0; cnt < uiNumLines-1; cnt++ )
- {
- memcpy( pDest, pSrc, uiLineSize );
- pDest += usDestWidth;
- pSrc += hImage->usWidth;
- }
- // Do last line
- memcpy( pDest, pSrc, uiLineSize );
- return( TRUE );
- }
- BOOLEAN Copy16BPPImageTo16BPPBuffer( HIMAGE hImage, BYTE *pDestBuf, UINT16 usDestWidth, UINT16 usDestHeight, UINT16 usX, UINT16 usY, SGPRect *srcRect )
- {
- UINT32 uiSrcStart, uiDestStart, uiNumLines, uiLineSize;
- UINT32 cnt;
- UINT16 *pDest, *pSrc;
- Assert( hImage != NULL );
- Assert( hImage->p16BPPData != NULL );
- // Validations
- CHECKF( usX >= 0 );
- CHECKF( usX < hImage->usWidth );
- CHECKF( usY >= 0 );
- CHECKF( usY < hImage->usHeight );
- CHECKF( srcRect->iRight > srcRect->iLeft );
- CHECKF( srcRect->iBottom > srcRect->iTop );
- // Determine memcopy coordinates
- uiSrcStart = srcRect->iTop * hImage->usWidth + srcRect->iLeft;
- uiDestStart = usY * usDestWidth + usX;
- uiNumLines = ( srcRect->iBottom - srcRect->iTop ) + 1;
- uiLineSize = ( srcRect->iRight - srcRect->iLeft ) + 1;
- CHECKF( usDestWidth >= uiLineSize );
- CHECKF( usDestHeight >= uiNumLines );
-
- // Copy line by line
- pDest = ( UINT16*)pDestBuf + uiDestStart;
- pSrc = hImage->p16BPPData + uiSrcStart;
- for( cnt = 0; cnt < uiNumLines-1; cnt++ )
- {
- memcpy( pDest, pSrc, uiLineSize * 2 );
- pDest += usDestWidth;
- pSrc += hImage->usWidth;
- }
- // Do last line
- memcpy( pDest, pSrc, uiLineSize * 2 );
- return( TRUE );
- }
- BOOLEAN Extract8BPPCompressedImageToBuffer( HIMAGE hImage, BYTE *pDestBuf )
- {
- return( FALSE );
- }
- BOOLEAN Extract16BPPCompressedImageToBuffer( HIMAGE hImage, BYTE *pDestBuf )
- {
- return( FALSE );
- }
- BOOLEAN Copy8BPPImageTo16BPPBuffer( HIMAGE hImage, BYTE *pDestBuf, UINT16 usDestWidth, UINT16 usDestHeight, UINT16 usX, UINT16 usY, SGPRect *srcRect )
- {
- UINT32 uiSrcStart, uiDestStart, uiNumLines, uiLineSize;
- UINT32 rows, cols;
- UINT8 *pSrc, *pSrcTemp;
- UINT16 *pDest, *pDestTemp;
- UINT16 *p16BPPPalette;
-
- p16BPPPalette = hImage->pui16BPPPalette;
- // Assertions
- Assert( p16BPPPalette != NULL );
- Assert( hImage != NULL );
- // Validations
- CHECKF( hImage->p16BPPData != NULL );
- CHECKF( usX >= 0 );
- CHECKF( usX < usDestWidth );
- CHECKF( usY >= 0 );
- CHECKF( usY < usDestHeight );
- CHECKF( srcRect->iRight > srcRect->iLeft );
- CHECKF( srcRect->iBottom > srcRect->iTop );
- // Determine memcopy coordinates
- uiSrcStart = srcRect->iTop * hImage->usWidth + srcRect->iLeft;
- uiDestStart = usY * usDestWidth + usX;
- uiNumLines = ( srcRect->iBottom - srcRect->iTop );
- uiLineSize = ( srcRect->iRight - srcRect->iLeft );
- CHECKF( usDestWidth >= uiLineSize );
- CHECKF( usDestHeight >= uiNumLines );
-
- // Convert to Pixel specification
- pDest = ( UINT16*)pDestBuf + uiDestStart;
- pSrc = hImage->p8BPPData + uiSrcStart;
- DbgMessage( TOPIC_HIMAGE, DBG_LEVEL_3, String( "Start Copying at %p", pDest ) );
- // For every entry, look up into 16BPP palette
- for( rows = 0; rows < uiNumLines-1; rows++ )
- {
- pDestTemp = pDest;
- pSrcTemp = pSrc;
- for ( cols = 0; cols < uiLineSize; cols++ )
- {
- *pDestTemp = p16BPPPalette[ *pSrcTemp ];
- pDestTemp++;
- pSrcTemp++;
- }
- pDest += usDestWidth;
- pSrc += hImage->usWidth;
- }
- // Do last line
- DbgMessage( TOPIC_HIMAGE, DBG_LEVEL_3, String( "End Copying at %p", pDest ) );
- return( TRUE );
- }
- UINT16 *Create16BPPPalette( SGPPaletteEntry *pPalette )
- {
- UINT16 *p16BPPPalette, r16, g16, b16, usColor;
- UINT32 cnt;
- UINT8 r,g,b;
- Assert( pPalette != NULL );
- p16BPPPalette = MemAlloc( sizeof( UINT16 ) * 256 );
- for ( cnt = 0; cnt < 256; cnt++ )
- {
- r = pPalette[ cnt ].peRed;
- g = pPalette[ cnt ].peGreen;
- b = pPalette[ cnt ].peBlue;
- if(gusRedShift < 0)
- r16=((UINT16)r>>abs(gusRedShift));
- else
- r16=((UINT16)r<<gusRedShift);
- if(gusGreenShift < 0)
- g16=((UINT16)g>>abs(gusGreenShift));
- else
- g16=((UINT16)g<<gusGreenShift);
- if(gusBlueShift < 0)
- b16=((UINT16)b>>abs(gusBlueShift));
- else
- b16=((UINT16)b<<gusBlueShift);
- usColor = (r16&gusRedMask)|(g16&gusGreenMask)|(b16&gusBlueMask);
- if(usColor==0)
- {
- if((r+g+b)!=0)
- usColor=BLACK_SUBSTITUTE | gusAlphaMask;
- }
- else
- usColor |= gusAlphaMask;
- p16BPPPalette[ cnt ] = usColor;
- }
- return( p16BPPPalette );
- }
- /**********************************************************************************************
- Create16BPPPaletteShaded
-
- Creates an 8 bit to 16 bit palette table, and modifies the colors as it builds.
-
- Parameters:
- rscale, gscale, bscale:
- Color mode: Percentages (255=100%) of color to translate into destination palette.
- Mono mode: Color for monochrome palette.
- mono:
- TRUE or FALSE to create a monochrome palette. In mono mode, Luminance values for
- colors are calculated, and the RGB color is shaded according to each pixel's brightness.
-
- This can be used in several ways:
- 1) To "brighten" a palette, pass down RGB values that are higher than 100% ( > 255) for all
- three. mono=FALSE.
- 2) To "darken" a palette, do the same with less than 100% ( < 255) values. mono=FALSE.
- 3) To create a "glow" palette, select mono=TRUE, and pass the color in the RGB parameters.
- 4) For gamma correction, pass in weighted values for each color.
- **********************************************************************************************/
- UINT16 *Create16BPPPaletteShaded( SGPPaletteEntry *pPalette, UINT32 rscale, UINT32 gscale, UINT32 bscale, BOOLEAN mono)
- {
- UINT16 *p16BPPPalette, r16, g16, b16, usColor;
- UINT32 cnt, lumin;
- UINT32 rmod, gmod, bmod;
- UINT8 r,g,b;
- Assert( pPalette != NULL );
- p16BPPPalette = MemAlloc( sizeof( UINT16 ) * 256 );
- for ( cnt = 0; cnt < 256; cnt++ )
- {
- if(mono)
- {
- lumin=(pPalette[ cnt ].peRed*299/1000)+ (pPalette[ cnt ].peGreen*587/1000)+(pPalette[ cnt ].peBlue*114/1000);
- rmod=(rscale*lumin)/256;
- gmod=(gscale*lumin)/256;
- bmod=(bscale*lumin)/256;
- }
- else
- {
- rmod = (rscale*pPalette[ cnt ].peRed/256);
- gmod = (gscale*pPalette[ cnt ].peGreen/256);
- bmod = (bscale*pPalette[ cnt ].peBlue/256);
- }
-
- r = (UINT8)__min(rmod, 255);
- g = (UINT8)__min(gmod, 255);
- b = (UINT8)__min(bmod, 255);
- if(gusRedShift < 0)
- r16=((UINT16)r>>(-gusRedShift));
- else
- r16=((UINT16)r<<gusRedShift);
- if(gusGreenShift < 0)
- g16=((UINT16)g>>(-gusGreenShift));
- else
- g16=((UINT16)g<<gusGreenShift);
- if(gusBlueShift < 0)
- b16=((UINT16)b>>(-gusBlueShift));
- else
- b16=((UINT16)b<<gusBlueShift);
- // Prevent creation of pure black color
- usColor = (r16&gusRedMask)|(g16&gusGreenMask)|(b16&gusBlueMask);
- if(usColor==0)
- {
- if((r+g+b)!=0)
- usColor=BLACK_SUBSTITUTE | gusAlphaMask;
- }
- else
- usColor |= gusAlphaMask;
- p16BPPPalette[ cnt ] = usColor;
- }
- return( p16BPPPalette );
- }
- // Convert from RGB to 16 bit value
- UINT16 Get16BPPColor( UINT32 RGBValue )
- {
- UINT16 r16, g16, b16, usColor;
- UINT8 r,g,b;
- r = SGPGetRValue( RGBValue );
- g = SGPGetGValue( RGBValue );
- b = SGPGetBValue( RGBValue );
- if(gusRedShift < 0)
- r16=((UINT16)r>>abs(gusRedShift));
- else
- r16=((UINT16)r<<gusRedShift);
- if(gusGreenShift < 0)
- g16=((UINT16)g>>abs(gusGreenShift));
- else
- g16=((UINT16)g<<gusGreenShift);
- if(gusBlueShift < 0)
- b16=((UINT16)b>>abs(gusBlueShift));
- else
- b16=((UINT16)b<<gusBlueShift);
- usColor=(r16&gusRedMask)|(g16&gusGreenMask)|(b16&gusBlueMask);
- // if our color worked out to absolute black, and the original wasn't
- // absolute black, convert it to a VERY dark grey to avoid transparency
- // problems
- if(usColor==0)
- {
- if(RGBValue!=0)
- usColor=BLACK_SUBSTITUTE | gusAlphaMask;
- }
- else
- usColor |= gusAlphaMask;
- return(usColor);
- }
- // Convert from 16 BPP to RGBvalue
- UINT32 GetRGBColor( UINT16 Value16BPP )
- {
- UINT16 r16, g16, b16;
- UINT32 r,g,b,val;
- r16 = Value16BPP & gusRedMask;
- g16 = Value16BPP & gusGreenMask;
- b16 = Value16BPP & gusBlueMask;
- if(gusRedShift < 0)
- r=((UINT32)r16<<abs(gusRedShift));
- else
- r=((UINT32)r16>>gusRedShift);
- if(gusGreenShift < 0)
- g=((UINT32)g16<<abs(gusGreenShift));
- else
- g=((UINT32)g16>>gusGreenShift);
- if(gusBlueShift < 0)
- b=((UINT32)b16<<abs(gusBlueShift));
- else
- b=((UINT32)b16>>gusBlueShift);
- r &= 0x000000ff;
- g &= 0x000000ff;
- b &= 0x000000ff;
- val = FROMRGB(r,g,b);
- return(val);
- }
- //*****************************************************************************
- //
- // ConvertToPaletteEntry
- //
- // Parameter List : Converts from RGB to SGPPaletteEntry
- //
- // Return Value pointer to the SGPPaletteEntry
- //
- // Modification History :
- // Dec 15th 1996 -> modified for use by Wizardry
- //
- //*****************************************************************************
- SGPPaletteEntry *ConvertRGBToPaletteEntry(UINT8 sbStart, UINT8 sbEnd, UINT8 *pOldPalette)
- {
- UINT16 Index;
- SGPPaletteEntry *pPalEntry;
- SGPPaletteEntry *pInitEntry;
- pPalEntry = (SGPPaletteEntry *)MemAlloc(sizeof(SGPPaletteEntry) * 256);
- pInitEntry = pPalEntry;
- DbgMessage(TOPIC_HIMAGE, DBG_LEVEL_0, "Converting RGB palette to SGPPaletteEntry");
- for(Index=0; Index <= (sbEnd-sbStart);Index++)
- {
- pPalEntry->peRed = *(pOldPalette + (Index*3));
- pPalEntry->peGreen = *(pOldPalette + (Index*3) + 1);
- pPalEntry->peBlue = *(pOldPalette + (Index*3) + 2);
- pPalEntry->peFlags = 0;
- pPalEntry++;
- }
- return pInitEntry;
- }
- BOOLEAN GetETRLEImageData( HIMAGE hImage, ETRLEData *pBuffer )
- {
- // Assertions
- Assert( hImage != NULL );
- Assert( pBuffer != NULL );
- // Create memory for data
- pBuffer->usNumberOfObjects = hImage->usNumberOfObjects;
- // Create buffer for objects
- pBuffer->pETRLEObject = MemAlloc( sizeof( ETRLEObject ) * pBuffer->usNumberOfObjects );
- CHECKF( pBuffer->pETRLEObject != NULL );
- // Copy into buffer
- memcpy( pBuffer->pETRLEObject, hImage->pETRLEObject, sizeof( ETRLEObject ) * pBuffer->usNumberOfObjects );
- // Allocate memory for pixel data
- pBuffer->pPixData = MemAlloc( hImage->uiSizePixData );
- CHECKF( pBuffer->pPixData != NULL );
- pBuffer->uiSizePixData = hImage->uiSizePixData;
- // Copy into buffer
- memcpy( pBuffer->pPixData, hImage->pPixData8, pBuffer->uiSizePixData );
- return( TRUE );
- }
- void ConvertRGBDistribution565To555( UINT16 * p16BPPData, UINT32 uiNumberOfPixels )
- {
- UINT16 * pPixel;
- UINT32 uiLoop;
-
- SplitUINT32 Pixel;
- pPixel = p16BPPData;
- for (uiLoop = 0; uiLoop < uiNumberOfPixels; uiLoop++)
- {
- // If the pixel is completely black, don't bother converting it -- DB
- if(*pPixel!=0)
- {
- // we put the 16 pixel bits in the UPPER word of uiPixel, so that we can
- // right shift the blue value (at the bottom) into the LOWER word to protect it
- Pixel.usHigher = *pPixel;
- Pixel.uiValue >>= 5;
- // get rid of the least significant bit of green
- Pixel.usHigher >>= 1;
- // now shift back into the upper word
- Pixel.uiValue <<= 5;
- // and copy back
- *pPixel = Pixel.usHigher | gusAlphaMask;
- }
- pPixel++;
- }
- }
- void ConvertRGBDistribution565To655( UINT16 * p16BPPData, UINT32 uiNumberOfPixels )
- {
- UINT16 * pPixel;
- UINT32 uiLoop;
-
- SplitUINT32 Pixel;
- pPixel = p16BPPData;
- for (uiLoop = 0; uiLoop < uiNumberOfPixels; uiLoop++)
- {
- // we put the 16 pixel bits in the UPPER word of uiPixel, so that we can
- // right shift the blue value (at the bottom) into the LOWER word to protect it
- Pixel.usHigher = *pPixel;
- Pixel.uiValue >>= 5;
- // get rid of the least significant bit of green
- Pixel.usHigher >>= 1;
- // shift to the right some more...
- Pixel.uiValue >>= 5;
- // so we can left-shift the red value alone to give it an extra bit
- Pixel.usHigher <<= 1;
- // now shift back and copy
- Pixel.uiValue <<= 10;
- *pPixel = Pixel.usHigher;
- pPixel++;
- }
- }
- void ConvertRGBDistribution565To556( UINT16 * p16BPPData, UINT32 uiNumberOfPixels )
- {
- UINT16 * pPixel;
- UINT32 uiLoop;
-
- SplitUINT32 Pixel;
- pPixel = p16BPPData;
- for (uiLoop = 0; uiLoop < uiNumberOfPixels; uiLoop++)
- {
- // we put the 16 pixel bits in the UPPER word of uiPixel, so that we can
- // right shift the blue value (at the bottom) into the LOWER word to protect it
- Pixel.usHigher = *pPixel;
- Pixel.uiValue >>= 5;
- // get rid of the least significant bit of green
- Pixel.usHigher >>= 1;
- // shift back into the upper word
- Pixel.uiValue <<= 5;
- // give blue an extra bit (blank in the least significant spot)
- Pixel.usHigher <<= 1;
- // copy back
- *pPixel = Pixel.usHigher;
- pPixel++;
- }
- }
- void ConvertRGBDistribution565ToAny( UINT16 * p16BPPData, UINT32 uiNumberOfPixels )
- {
- UINT16 * pPixel;
- UINT32 uiRed, uiGreen, uiBlue, uiTemp, uiLoop;
- pPixel = p16BPPData;
- for (uiLoop = 0; uiLoop < uiNumberOfPixels; uiLoop++)
- {
- // put the 565 RGB 16-bit value into a 32-bit RGB value
- uiRed = (*pPixel) >> 11;
- uiGreen = (*pPixel & 0x07E0) >> 5;
- uiBlue = (*pPixel & 0x001F);
- uiTemp = FROMRGB(uiRed,uiGreen,uiBlue);
- // then convert the 32-bit RGB value to whatever 16 bit format is used
- *pPixel = Get16BPPColor( uiTemp );
- pPixel++;
- }
- }
|