Main Page | Alphabetical List | Compound List | File List | Compound Members | File Members

bitmap_blitdata.c

Go to the documentation of this file.
00001 /****************************************************************************************/
00002 /*  Bitmap_BlitData.c                                                                   */
00003 /*                                                                                      */
00004 /*  Author: Charles Bloom                                                               */
00005 /*  Description:  The Bitmap_BlitData function                                          */
00006 /*                                      Does all format conversions                                                                                     */
00007 /*                                                                                      */
00008 /*  The contents of this file are subject to the Genesis3D Public License               */
00009 /*  Version 1.01 (the "License"); you may not use this file except in                   */
00010 /*  compliance with the License. You may obtain a copy of the License at                */
00011 /*  http://www.genesis3d.com                                                            */
00012 /*                                                                                      */
00013 /*  Software distributed under the License is distributed on an "AS IS"                 */
00014 /*  basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See                */
00015 /*  the License for the specific language governing rights and limitations              */
00016 /*  under the License.                                                                  */
00017 /*                                                                                      */
00018 /*  The Original Code is Genesis3D, released March 25, 1999.                            */
00019 /*Genesis3D Version 1.1 released November 15, 1999                            */
00020 /*  Copyright (C) 1999 WildTangent, Inc. All Rights Reserved           */
00021 /*                                                                                      */
00022 /****************************************************************************************/
00023 
00024 /*}{*********************************************************************/
00025 
00026 #include        <math.h>
00027 #include        <time.h>
00028 #include        <stdio.h>
00029 #include        <assert.h>
00030 #include        <stdlib.h>
00031 #include        <string.h>
00032 
00033 #include        "basetype.h"
00034 #include        "getypes.h"
00035 #include        "ram.h"
00036 
00037 #include        "bitmap.h"
00038 #include        "bitmap._h"
00039 #include        "bitmap.__h"
00040 #include        "bitmap_blitdata.h"
00041 
00042 #include        "vfile.h"
00043 #include        "ErrorLog.h"
00044 
00045 #include        "palcreate.h"
00046 #include        "palettize.h"
00047 
00048 #include        "tsc.h"
00049 
00050 #ifdef DO_TIMER
00051 #include        "timer.h"
00052 #endif
00053 
00054 //#define DONT_USE_ASM
00055 
00056 /*}{*********************************************************************/
00057 
00058 // parameters to the main BlitData call are set up in here & shared
00059 //  with all the children functions
00060 
00061 // this may actually be better than being thread-friendly
00062 // because we prevent cache-thrashing
00063 
00064 static int SrcXtra,DstXtra;
00065 static int SrcPelBytes,DstPelBytes;
00066 static int SrcRowBytes,DstRowBytes;
00067 static int SrcXtraBytes,DstXtraBytes;
00068 static const gePixelFormat_Operations *SrcOps,*DstOps;
00069 static gePixelFormat SrcFormat,DstFormat;
00070 
00071 static const geBitmap_Info * SrcInfo;
00072 static           geBitmap_Info * DstInfo;
00073 static const void *SrcData;
00074 static           void *DstData;
00075 static const geBitmap *SrcBmp;
00076 static           geBitmap *DstBmp;
00077 static const geBitmap_Palette *SrcPal;
00078 static           geBitmap_Palette *DstPal;
00079 static int SizeX,SizeY;
00080 
00081 static gePixelFormat_Decomposer         SrcDecomposePixel;
00082 static gePixelFormat_Composer           DstComposePixel;
00083 static gePixelFormat_ColorGetter        SrcGetColor;
00084 static gePixelFormat_ColorPutter        DstPutColor;
00085 static gePixelFormat_PixelGetter        SrcGetPixel;
00086 static gePixelFormat_PixelPutter        DstPutPixel;
00087 
00088 /*}{*********************************************************************/
00089 
00090 geBoolean BlitData_Raw(void);
00091 geBoolean BlitData_SameFormat(void);
00092 geBoolean BlitData_Palettize(void);
00093 geBoolean BlitData_DePalettize(void);
00094 geBoolean BlitData_FromSeparateAlpha(void);
00095 geBoolean BlitData_ToSeparateAlpha(void);
00096 
00097 geBoolean geBitmap_BlitData_Sub(        const geBitmap_Info * iSrcInfo,const void *iSrcData, const geBitmap *iSrcBmp,
00098                                                                 geBitmap_Info * iDstInfo,void *iDstData,        const geBitmap *iDstBmp,
00099                                                                 int iSizeX,int iSizeY)
00100 {
00101 
00102         // warming up...
00103 
00104         SrcInfo = iSrcInfo;
00105         DstInfo = iDstInfo;
00106         SrcData = iSrcData;
00107         DstData = iDstData;
00108         SrcBmp  = iSrcBmp;
00109         DstBmp  = (geBitmap *)iDstBmp;
00110         SizeX   = iSizeX;
00111         SizeY   = iSizeY;
00112 
00113         assert(SrcInfo && SrcData && DstInfo && DstData);
00114 
00115         // SrcData & DstData may be the same!
00116         // SrcBmp  & DstBmp  may be NULL !
00117 
00118         if ( SizeX > SrcInfo->Width || SizeX > DstInfo->Width ||
00119                  SizeY > SrcInfo->Height|| SizeY > DstInfo->Height)
00120         {
00121                 geErrorLog_AddString(-1,"Bitmap_BlitData : size mismatch", NULL);       
00122                 return GE_FALSE;
00123         }
00124 
00125         SrcFormat = SrcInfo->Format;
00126         DstFormat = DstInfo->Format;
00127 
00128         SrcOps = gePixelFormat_GetOperations(SrcFormat);
00129         DstOps = gePixelFormat_GetOperations(DstFormat);
00130 
00131         if ( ! SrcOps || ! DstOps )
00132                 {
00133                         geErrorLog_AddString(-1,"Bitmap_BlitData: SrcOps != DstOps",NULL);
00134                         return GE_FALSE;
00135                 }
00136                 
00137         SrcPelBytes = SrcOps->BytesPerPel;
00138         DstPelBytes = DstOps->BytesPerPel;
00139 
00140         SrcRowBytes = SrcPelBytes * SrcInfo->Stride;
00141         DstRowBytes = DstPelBytes * DstInfo->Stride;
00142 
00143         SrcXtra = SrcInfo->Stride - SizeX;
00144         DstXtra = DstInfo->Stride - SizeX;
00145 
00146         SrcXtraBytes = SrcXtra * SrcPelBytes;
00147         DstXtraBytes = DstXtra * DstPelBytes;
00148 
00149         DstComposePixel         = DstOps->ComposePixel;
00150         DstPutColor                     = DstOps->PutColor;
00151         DstPutPixel                     = DstOps->PutPixel;
00152         SrcDecomposePixel       = SrcOps->DecomposePixel;
00153         SrcGetColor                     = SrcOps->GetColor;
00154         SrcGetPixel                     = SrcOps->GetPixel;
00155 
00156         SrcPal = SrcInfo->Palette;
00157         if ( ! SrcPal && SrcBmp )
00158                 SrcPal = geBitmap_GetPalette(SrcBmp);
00159         DstPal = DstInfo->Palette;
00160         if ( ! DstPal && DstBmp )
00161                 DstPal = geBitmap_GetPalette(DstBmp);
00162 
00163         // all systems go!
00164 
00167         if ( gePixelFormat_HasPalette(SrcFormat) && ! SrcPal )
00168         {
00169                 geErrorLog_AddString(-1, "geBitmap_BlitData:  Palettized format, with no palette.", NULL);
00170                 return GE_FALSE;
00171         }
00172 
00173         if ( SrcPal && gePixelFormat_HasPalette(DstFormat) )
00174         {
00175                 if ( ! DstInfo->Palette )
00176                 {
00177                 gePixelFormat Format;
00178                         Format = SrcPal->Format;
00179                         if ( ! gePixelFormat_HasAlpha(Format) )
00180                         {
00181                                 if ( SrcInfo->HasColorKey && ! DstInfo->HasColorKey )
00182                                         Format = GE_PIXELFORMAT_32BIT_ARGB;
00183                         }
00184                         geBitmap_AllocPalette(DstBmp,Format,DstBmp->Driver);
00185                         if ( ! DstInfo->Palette )
00186                                 DstInfo->Palette = geBitmap_GetPalette(DstBmp);
00187                 }
00188                 DstPal = DstInfo->Palette;
00189                 if ( ! DstPal )
00190                 {
00191                         geErrorLog_AddString(-1, "geBitmap_BlitData:  couldn't alloc new dest palette.", NULL);
00192                         return GE_FALSE;
00193                 }
00194 
00195                 if ( ! geBitmap_Palette_Copy(SrcPal,DstPal) )
00196                 {
00197                         geErrorLog_AddString(-1,"Bitmap_BlitData : Palette_Copy failed", NULL);
00198                         return GE_FALSE;
00199                 }
00200                 
00201                 if ( SrcInfo->HasColorKey )
00202                 {
00203                         if ( ! geBitmap_Palette_SetEntryColor(DstInfo->Palette,SrcInfo->ColorKey,0,0,0,0) )
00204                         {
00205                                 geErrorLog_AddString(-1,"Bitmap_BlitData: geBitmap_Palette_SetEntryColor failed",NULL);
00206                                 return GE_FALSE;
00207                         }
00208                 }
00209         }
00210 
00211         /****
00212         **
00213         *
00214                 modes:
00215                         0. types are same
00216                         1. Wavelet <-> raw
00217                         2. Pal -> raw (easy)    (now raw means "not wavelet or pal")
00218                         3. raw -> Pal (hard)
00219                         4. raw <-> raw (just bit-ops)
00220 
00221                 each of these also exists for separate alpha types
00222         *
00223         **
00224          ****/
00225 
00226         /****/
00227         
00228         if (    SrcBmp && SrcBmp->Alpha && SrcBmp->Alpha->LockOwner && 
00229                 DstBmp && DstBmp->Alpha && DstBmp->Alpha->LockOwner )
00230         {
00231                 if ( ! geBitmap_BlitBitmap(SrcBmp->Alpha,DstBmp->Alpha) )
00232                         {
00233                                 geErrorLog_AddString(-1,"geBitmap_BlitData:  geBitmap_BlitBitmap Failed",NULL);
00234                                 return GE_FALSE;
00235                         }
00236                 // now continue through to blit the main bitmap
00237         }
00238         else if ( SrcBmp && SrcBmp->Alpha && SrcBmp->Alpha->LockOwner && 
00239                         ( gePixelFormat_HasAlpha(DstFormat) || DstInfo->HasColorKey ) )
00240         {
00241                 // there is no separate alpha -> color key conversion
00242                 // note that we cannot add separate alpha -> CK because the 
00243                 // separate-alpha *target* type has colorkey too !
00244                 if (BlitData_FromSeparateAlpha()==GE_FALSE)
00245                         {
00246                                 geErrorLog_AddString(-1,"geBitmap_BlitData:  geBitmap_FromSeparateAlpha Failed",NULL);
00247                                 return GE_FALSE;
00248                         }
00249                 else
00250                         return GE_TRUE;
00251 
00252         }
00253         else if ( DstBmp && DstBmp->Alpha && DstBmp->Alpha->LockOwner && 
00254                         gePixelFormat_HasAlpha(SrcFormat) )
00255         {
00256                 // there is no separate alpha -> color key conversion
00257                 // note that we cannot add separate alpha -> CK because the 
00258                 // separate-alpha *target* type has colorkey too !
00259                 if (BlitData_ToSeparateAlpha()==GE_FALSE)
00260                         {
00261                                 geErrorLog_AddString(-1,"geBitmap_BlitData:  geBitmap_ToSeparateAlpha Failed",NULL);
00262                                 return GE_FALSE;
00263                         }
00264                 else
00265                         return GE_TRUE;
00266         }
00267 
00268         /****/
00269 
00270         if (    SrcFormat == GE_PIXELFORMAT_WAVELET ||
00271                         DstFormat == GE_PIXELFORMAT_WAVELET )
00272         {
00273                 geErrorLog_AddString(-1,"Bitmap_BlitData : no wavelets in Genesis 1.0", NULL);  
00274                 return GE_FALSE;
00275         }
00276         else if ( SrcFormat == DstFormat )
00277         {
00278                 if (BlitData_SameFormat()==GE_FALSE)
00279                         {
00280                                 geErrorLog_AddString(-1,"geBitmap_BlitData: BlitData_SameFormat failed",NULL);
00281                                 return GE_FALSE;
00282                         }
00283                 else
00284                         return GE_TRUE;
00285         }
00286         else if (       gePixelFormat_HasPalette(SrcFormat) ||
00287                                 gePixelFormat_HasPalette(DstFormat) )
00288         {
00289                 assert(SrcFormat != DstFormat);
00290                 if (    gePixelFormat_HasPalette(SrcFormat) &&
00291                                 gePixelFormat_HasPalette(DstFormat) )
00292                         {
00293                                 geErrorLog_AddString(-1,"geBitmap_BlitData:  two different palettized.",NULL);
00294                                 return GE_FALSE;        // already picked up by SameFormat , or two different palettized = abort!
00295                         }
00296 
00297                 if ( gePixelFormat_HasPalette(SrcFormat) )
00298                 {
00299                         if (BlitData_DePalettize()==GE_FALSE)
00300                                 {
00301                                         geErrorLog_AddString(-1,"geBitmap_BlitData:  BlitData_DePalettize() failed.",NULL);
00302                                         return GE_FALSE;        
00303                                 }
00304                         else
00305                                 return GE_TRUE;
00306                 }
00307                 else
00308                 {
00309                         if ( ! DstInfo->Palette )
00310                         {
00311                                 // make it
00312                                 if ( DstBmp && DstBmp->Driver )
00313                                 {
00314                                 gePixelFormat Format;
00315                                         Format = SrcInfo->Palette ? SrcInfo->Palette->Format : GE_PIXELFORMAT_32BIT_XRGB;
00316                                         if ( ! gePixelFormat_HasAlpha(Format) )
00317                                         {
00318                                                 if ( SrcInfo->HasColorKey && ! DstInfo->HasColorKey )
00319                                                         Format = GE_PIXELFORMAT_32BIT_ARGB;
00320                                         }
00321                                         geBitmap_AllocPalette(DstBmp,Format,DstBmp->Driver);
00322                                         if ( ! DstInfo->Palette )
00323                                                 DstInfo->Palette = geBitmap_GetPalette(DstBmp);
00324                                 }
00325                                 else
00326                                 {
00327                                         DstInfo->Palette = geBitmap_Palette_Create(PALETTE_FORMAT_DEFAULT,256);
00328                                 }
00329                                 if ( ! DstInfo->Palette )
00330                                 {
00331                                         geErrorLog_AddString(-1,"Bitmap_BlitData : Pal create failed", NULL);   
00332                                         return GE_FALSE;
00333                                 }
00334 
00335                                 if ( SrcPal )
00336                                 {
00337                                         geBitmap_Palette_Copy(SrcPal,DstInfo->Palette);
00338                                 }
00339                                 else if ( DstPal )
00340                                 {
00341                                         geBitmap_Palette_Copy(DstPal,DstInfo->Palette);
00342                                 }
00343                                 else // Nobody had a palette !
00344                                 {
00345                                 geBitmap_Palette * NewPal;
00346                                 geBitmap_Info Info;
00347                                         Info = *SrcInfo;
00348                                         Info.Width = SizeX;
00349                                         Info.Height = SizeY;
00350                                         NewPal = createPalette(&Info,SrcData);
00351                                         if ( ! NewPal )
00352                                         {
00353                                                 geErrorLog_AddString(-1,"Bitmap_BlitData : createPalette failed", NULL);        
00354                                                 return GE_FALSE;
00355                                         }
00356                                         geBitmap_Palette_Copy(NewPal,DstInfo->Palette);
00357                                         if ( SrcBmp && ((SizeX*SizeY) > ((SrcInfo->Width * SrcInfo->Height)>>2)) )
00358                                         {
00359                                                 geBitmap_SetPalette((geBitmap *)SrcBmp,NewPal);
00360                                         }
00361                                         geBitmap_Palette_Destroy(&NewPal);
00362                                 }
00363 
00364                                 DstPal = DstInfo->Palette;
00365 
00366                                 SrcPal = SrcInfo->Palette;
00367                                 if ( ! SrcPal && SrcBmp )
00368                                         SrcPal = geBitmap_GetPalette(SrcBmp);
00369                         }
00370 
00371                         if (BlitData_Palettize()==GE_FALSE)
00372                                 {
00373                                         geErrorLog_AddString(-1,"geBitmap_BlitData:  BlitData_Palettize failed.",NULL);
00374                                         return GE_FALSE;        
00375                                 }
00376                         else
00377                                 return GE_TRUE;
00378                 }
00379         }
00380         else
00381         {
00382                 if (BlitData_Raw()==GE_FALSE)
00383                         {
00384                                 geErrorLog_AddString(-1,"geBitmap_BlitData:  BlitData_Raw failed.",NULL);
00385                                 return GE_FALSE;        
00386                         }
00387                 else
00388                         return GE_TRUE; 
00389         }
00390 
00391         assert(0);
00392         // must have returned before here
00393         //return GE_FALSE;
00394 }
00395 
00396 geBoolean geBitmap_BlitData(    const geBitmap_Info * iSrcInfo,const void *iSrcData, const geBitmap *iSrcBmp,
00397                                                                 geBitmap_Info * iDstInfo,void *iDstData,        const geBitmap *iDstBmp,
00398                                                                 int iSizeX,int iSizeY)
00399 {
00400 geBoolean Ret;
00401 
00402         Ret = geBitmap_BlitData_Sub(    
00403                                                         iSrcInfo,iSrcData,iSrcBmp,
00404                                                         iDstInfo,iDstData,iDstBmp,      
00405                                                         iSizeX,iSizeY);
00406 
00407 return Ret;
00408 }
00409 
00410 /*}{*********************************************************************/
00411 
00412 geBoolean BlitData_Raw(void)
00413 {
00414 int x,y;
00415 char *SrcPtr,*DstPtr;
00416 int R,G,B,A;
00417 uint32 ColorKey,Pixel;
00418 
00419         if ( ! SrcOps || ! DstOps )
00420                 return GE_FALSE;
00421 
00422         SrcPtr = (char *)SrcData;
00423         DstPtr = (char *)DstData;
00424 
00425         // this generic converter is pretty slow.
00426         // fortunately genesis uses mostly the (Pal -> UnPal) conversion
00427         // or the (Wavelet -> UnPal) conversion
00428 
00429         if ( SrcPelBytes == 0 || DstPelBytes == 0 ) 
00430         {
00431                 geErrorLog_AddString(-1,"Bitmap_BlitData : invalid format", NULL);
00432                 return GE_FALSE;
00433         }
00434         else if ( SrcOps->AMask && ! (DstOps->AMask) && DstInfo->HasColorKey )
00435         {
00436                 ColorKey = DstInfo->ColorKey;
00437 
00438                 // special case for "Src has alpha & Dst doesn't, but has ColorKey"
00439 
00440                 for(y=SizeY;y--;)
00441                 {
00442                         for(x=SizeX;x--;)
00443                         {
00444                                 SrcGetColor(&SrcPtr,&R,&G,&B,&A);
00445                                 if ( A < ALPHA_TO_TRANSPARENCY_THRESHOLD )
00446                                 {
00447                                         Pixel = ColorKey;
00448                                 }
00449                                 else
00450                                 {
00451                                         Pixel = DstComposePixel(R,G,B,A);
00452                                         if ( Pixel == ColorKey )
00453                                         {
00454                                                 Pixel ^= 1;
00455                                         }
00456                                 }
00457                                 DstPutPixel(&DstPtr,Pixel);
00458                         }
00459                         SrcPtr += SrcXtraBytes;
00460                         DstPtr += DstXtraBytes;
00461                 }
00462 
00463         return GE_TRUE;
00464         }
00465         else if ( SrcInfo->HasColorKey && DstInfo->HasColorKey )
00466         {
00467         uint32 DstColorKey;
00468 
00469                 ColorKey = SrcInfo->ColorKey;
00470                 DstColorKey = DstInfo->ColorKey;
00471 
00472                 for(y=SizeY;y--;)
00473                 {
00474                         for(x=SizeX;x--;)
00475                         {
00476                                 Pixel = SrcGetPixel(&SrcPtr);
00477                                 if ( Pixel == ColorKey )
00478                                 {
00479                                         DstPutPixel(&DstPtr,DstColorKey);
00480                                 }
00481                                 else
00482                                 {
00483                                         SrcDecomposePixel(Pixel,&R,&G,&B,&A);
00484                                         Pixel = DstComposePixel(R,G,B,A);
00485                                         if ( Pixel == DstColorKey )
00486                                                 Pixel ^= 1;
00487                                         DstPutPixel(&DstPtr,Pixel);
00488                                 }
00489                         }
00490                         SrcPtr += SrcXtraBytes;
00491                         DstPtr += DstXtraBytes;
00492                 }
00493 
00494         return GE_TRUE;
00495         }
00496         else if ( DstInfo->HasColorKey )
00497         {
00498                 ColorKey = DstInfo->ColorKey;
00499 
00500                 for(y=SizeY;y--;)
00501                 {
00502                         for(x=SizeX;x--;)
00503                         {
00504                                 SrcGetColor(&SrcPtr,&R,&G,&B,&A);
00505                                 Pixel = DstComposePixel(R,G,B,A);
00506                                 if ( Pixel == ColorKey )
00507                                 {
00508                                         Pixel ^= 1;
00509                                 }
00510                                 DstPutPixel(&DstPtr,Pixel);
00511                         }
00512                         SrcPtr += SrcXtraBytes;
00513                         DstPtr += DstXtraBytes;
00514                 }
00515 
00516         return GE_TRUE;
00517         }
00518         else if ( SrcInfo->HasColorKey )
00519         {
00520                 // generic converter does the cases we don't understand
00521 
00522                 ColorKey = SrcInfo->ColorKey;
00523 
00524                 for(y=SizeY;y--;)
00525                 {
00526                         for(x=SizeX;x--;)
00527                         {
00528                                 Pixel = SrcGetPixel(&SrcPtr);
00529                                 if ( Pixel == ColorKey )
00530                                 {
00531                                         DstPutColor(&DstPtr,0,0,0,0);
00532                                 }
00533                                 else
00534                                 {
00535                                         SrcDecomposePixel(Pixel,&R,&G,&B,&A);
00536                                         DstPutColor(&DstPtr,R,G,B,A);
00537                                 }
00538                         }
00539                         SrcPtr += SrcXtraBytes;
00540                         DstPtr += DstXtraBytes;
00541                 }
00542 
00543         return GE_TRUE;
00544         }
00545         else
00546         {
00547                 for(y=SizeY;y--;)
00548                 {
00549                         for(x=SizeX;x--;)
00550                         {
00551                                 SrcGetColor(&SrcPtr,&R,&G,&B,&A);
00552                                 DstPutColor(&DstPtr,R,G,B,A);
00553                         }
00554                         SrcPtr += SrcXtraBytes;
00555                         DstPtr += DstXtraBytes;
00556                 }
00557 
00558         return GE_TRUE;
00559         }
00560 }
00561 
00562 /*}{*********************************************************************/
00563 
00564 geBoolean BlitData_FromSeparateAlpha(void)
00565 {
00566 geBitmap_Info AlphaInfo;
00567 void * AlphaData;
00568 uint8 *SrcPtr,*DstPtr,*AlphaPtr;
00569 int x,y,R,G,B,A;
00570 uint32 ColorKey,Pixel;
00571 int AlphaXtra;
00572 
00573         /*******
00574         **
00575                 support the extra Alpha Bmp
00576                 the common case is 8bit + 8bit -> 4444
00577 
00578                 we're pretty lazy about this; it's not optimized for speed
00579 
00580         **
00581          ******/
00582 
00583         #pragma message("Bitmap_BlitData: inconsistent handling of separates with color keys!")
00584 
00585         SrcPtr = (uint8 *)SrcData;
00586         DstPtr = (uint8 *)DstData;
00587 
00588         if ( ! geBitmap_GetInfo(SrcBmp->Alpha,&AlphaInfo,NULL) )
00589                 return GE_FALSE;
00590         if ( AlphaInfo.Format != GE_PIXELFORMAT_8BIT_GRAY )
00591         {
00592                 geErrorLog_AddString(-1,"Bitmap_BlitData : Alpha must be grayscale", NULL);
00593                 return GE_FALSE;
00594         }
00595 
00596         AlphaData = geBitmap_GetBits(SrcBmp->Alpha);
00597         if ( ! AlphaData )
00598                 return GE_FALSE;
00599 
00600         AlphaPtr = (uint8 *)AlphaData;
00601         AlphaXtra = AlphaInfo.Stride - SizeX;
00602 
00603         if ( gePixelFormat_HasPalette(SrcFormat) )
00604         {
00605                 if ( SrcFormat == DstFormat )
00606                 {
00607                 uint8 Pixel,DstColorKey;
00608 
00609                         assert(DstInfo->HasColorKey);
00610                         
00611                         DstColorKey = (uint8)DstInfo->ColorKey;
00612                         for(y=SizeY;y--;)
00613                         {
00614                                 for(x=SizeX;x--;)
00615                                 {
00616                                         Pixel = *SrcPtr++;
00617                                         A = *AlphaPtr++;
00618                                         if ( A < ALPHA_TO_TRANSPARENCY_THRESHOLD )
00619                                                 *DstPtr++ = DstColorKey;
00620                                         else
00621                                                 *DstPtr++ = Pixel;
00622                                 }
00623                                 SrcPtr += SrcXtra;
00624                                 DstPtr += DstXtraBytes;
00625                                 AlphaPtr += AlphaXtra;
00626                         }
00627                         return GE_TRUE;
00628                 }
00629                 else if ( SrcFormat == GE_PIXELFORMAT_8BIT )
00630                 {
00631                 uint8 *PalPtr,PalData[768];
00632                 int pal;
00633 
00634                         if ( ! geBitmap_Palette_GetData(SrcPal,PalData,GE_PIXELFORMAT_24BIT_RGB,256) )
00635                                 return GE_FALSE;
00636 
00637                         // with seperate alpha
00638 
00639                         if ( ! gePixelFormat_HasAlpha(DstFormat) && DstInfo->HasColorKey )
00640                         {
00641                         uint32 Pixel,DstColorKey;
00642                                 // source is palettized
00643                                 // dest has color key and no alpha
00644                                 DstColorKey = DstInfo->ColorKey;
00645                                 for(y=SizeY;y--;)
00646                                 {
00647                                         for(x=SizeX;x--;)
00648                                         {
00649                                                 pal = *SrcPtr++;
00650                                                 PalPtr = &PalData[3*pal];
00651                                                 R = *PalPtr++;
00652                                                 G = *PalPtr++;
00653                                                 B = *PalPtr;
00654                                                 A = *AlphaPtr++;
00655                                                 if ( A < 128 )
00656                                                 {
00657                                                         DstPutPixel(&DstPtr,DstColorKey);
00658                                                 }
00659                                                 else
00660                                                 {
00661                                                         Pixel = DstComposePixel(R,G,B,255);
00662                                                         if ( Pixel == DstColorKey )
00663                                                                 Pixel ^= 1;
00664                                                         DstPutPixel(&DstPtr,Pixel);
00665                                                 }
00666                                         }
00667                                         SrcPtr += SrcXtra;
00668                                         DstPtr += DstXtraBytes;
00669                                         AlphaPtr += AlphaXtra;
00670                                 }
00671                         }
00672                         else if ( DstInfo->HasColorKey )
00673                         {
00674                         uint32 Pixel,DstColorKey;
00675                                 // source is palettized
00676                                 // dest has alpha and color key
00677                                 DstColorKey = DstInfo->ColorKey;
00678                                 for(y=SizeY;y--;)
00679                                 {
00680                                         for(x=SizeX;x--;)
00681                                         {
00682                                                 pal = *SrcPtr++;
00683                                                 PalPtr = &PalData[3*pal];
00684                                                 R = *PalPtr++;
00685                                                 G = *PalPtr++;
00686                                                 B = *PalPtr;
00687                                                 A = *AlphaPtr++;
00688                                                 Pixel = DstComposePixel(R,G,B,A);
00689                                                 if ( Pixel == DstColorKey )
00690                                                         Pixel ^= 1;
00691                                                 DstPutPixel(&DstPtr,Pixel);
00692                                         }
00693                                         SrcPtr += SrcXtra;
00694                                         DstPtr += DstXtraBytes;
00695                                         AlphaPtr += AlphaXtra;
00696                                 }
00697                         }
00698                         else
00699                         {
00700                                 // source is palettized
00701                                 // dest has alpha and no color key
00702                                 for(y=SizeY;y--;)
00703                                 {
00704                                         for(x=SizeX;x--;)
00705                                         {
00706                                                 pal = *SrcPtr++;
00707                                                 PalPtr = &PalData[3*pal];
00708                                                 R = *PalPtr++;
00709                                                 G = *PalPtr++;
00710                                                 B = *PalPtr;
00711                                                 A = *AlphaPtr++;
00712                                                 DstPutColor(&DstPtr,R,G,B,A);
00713                                         }
00714                                         SrcPtr += SrcXtra;
00715                                         DstPtr += DstXtraBytes;
00716                                         AlphaPtr += AlphaXtra;
00717                                 }
00718                         }
00719 
00720                         return GE_TRUE;
00721                 }
00722                 else
00723                 {
00724                         return GE_FALSE;
00725                 }
00726                 assert("should not get here" == NULL);
00727         }
00728         else
00729         {
00730                 // this generic converter is pretty slow.
00731                 // fortunately genesis uses mostly the (Pal -> UnPal) conversion
00732                 // or the (Wavelet -> UnPal) conversion
00733 
00734                 // Src is not palettized
00735 
00736                 assert( ! SrcOps->AMask );
00737                 assert( DstOps->AMask || DstInfo->HasColorKey );
00738 
00739                 // <> doesn't do -> palettize
00740                 //      should never get a (separates)->(palettized) with current driver, but bad to assume...
00741                 // perhaps the best thing is to do separates -> 32bitRGBA then do 32bitRGBA -> Dest with the normal converters
00742 
00743                 if ( gePixelFormat_HasPalette(DstFormat) )
00744                 {
00745                         geErrorLog_AddString(-1,"Bitmap_BlitData : FromSeparateAlpha : doesn't do Palettize!", NULL);
00746                         return GE_FALSE;
00747                 }
00748 
00749                 if ( SrcPelBytes == 0 ) 
00750                 {
00751                         geErrorLog_AddString(-1,"Bitmap_BlitData : FromSeparateAlpha : bad Src format", NULL);
00752                         return GE_FALSE;
00753                 }
00754                 else if ( DstPelBytes == 0 || ! DstPutColor || ! DstComposePixel ) 
00755                 {
00756                         geErrorLog_AddString(-1,"Bitmap_BlitData : FromSeparateAlpha : bad Dst format", NULL);
00757                         return GE_FALSE;
00758                 }
00759 
00760 
00761                 if ( DstOps->AMask )
00762                 {
00763 
00764                         //separates -> alpha
00765 
00766                         if ( SrcInfo->HasColorKey && DstInfo->HasColorKey )
00767                         {
00768                         uint32 DstColorKey;
00769 
00770                                 ColorKey        = SrcInfo->ColorKey;
00771                                 DstColorKey     = DstInfo->ColorKey;
00772 
00773                                 // with seperate alpha
00774 
00775                                 for(y=SizeY;y--;)
00776                                 {
00777                                         for(x=SizeX;x--;)
00778                                         {
00779                                                 Pixel = SrcGetPixel(&SrcPtr);
00780                                                 if ( Pixel == ColorKey )
00781                                                 {
00782                                                         AlphaPtr++;
00783                                                         DstPutPixel(&DstPtr,DstColorKey);
00784                                                 }
00785                                                 else
00786                                                 {
00787                                                         SrcDecomposePixel(Pixel,&R,&G,&B,&A);
00788                                                         A = *AlphaPtr++;
00789                                                         Pixel = DstComposePixel(R,G,B,A);
00790                                                         if ( Pixel == DstColorKey )
00791                                                                 Pixel ^= 1;
00792                                                         DstPutPixel(&DstPtr,Pixel);
00793                                                 }
00794                                         }
00795                                         SrcPtr += SrcXtraBytes;
00796                                         DstPtr += DstXtraBytes;
00797                                         AlphaPtr += AlphaXtra;
00798                                 }
00799 
00800                         return GE_TRUE;
00801                         }
00802                         else if ( DstInfo->HasColorKey )
00803                         {
00804                                 ColorKey = DstInfo->ColorKey;
00805 
00806                                 // with seperate alpha
00807 
00808                                 for(y=SizeY;y--;)
00809                                 {
00810                                         for(x=SizeX;x--;)
00811                                         {
00812                                                 SrcGetColor(&SrcPtr,&R,&G,&B,&A);
00813                                                 A = *AlphaPtr++;
00814                                                 Pixel = DstComposePixel(R,G,B,A);
00815                                                 if ( Pixel == ColorKey )
00816                                                 {
00817                                                         Pixel ^= 1;
00818                                                 }
00819                                                 DstPutPixel(&DstPtr,Pixel);
00820                                         }
00821                                         SrcPtr += SrcXtraBytes;
00822                                         DstPtr += DstXtraBytes;
00823                                         AlphaPtr += AlphaXtra;
00824                                 }
00825 
00826                         return GE_TRUE;
00827                         }
00828                         else if ( SrcInfo->HasColorKey )
00829                         {
00830                                 // with seperate alpha
00831 
00832                                 ColorKey = SrcInfo->ColorKey;
00833 
00834                                 for(y=SizeY;y--;)
00835                                 {
00836                                         for(x=SizeX;x--;)
00837                                         {
00838                                                 Pixel = SrcGetPixel(&SrcPtr);
00839                                                 if ( Pixel == ColorKey )
00840                                                 {
00841                                                         AlphaPtr++;
00842                                                         DstPutColor(&DstPtr,0,0,0,0);
00843                                                 }
00844                                                 else
00845                                                 {
00846                                                         SrcDecomposePixel(Pixel,&R,&G,&B,&A);
00847                                                         A = *AlphaPtr++;
00848                                                         DstPutColor(&DstPtr,R,G,B,A);
00849                                                 }
00850                                         }
00851                                         SrcPtr += SrcXtraBytes;
00852                                         DstPtr += DstXtraBytes;
00853                                         AlphaPtr += AlphaXtra;
00854                                 }
00855 
00856                         return GE_TRUE;
00857                         }
00858                         else
00859                         {
00860                                 // with seperate alpha
00861                                 for(y=SizeY;y--;)
00862                                 {
00863                                         for(x=SizeX;x--;)
00864                                         {
00865                                                 SrcGetColor(&SrcPtr,&R,&G,&B,&A);
00866                                                 A = *AlphaPtr++;
00867                                                 DstPutColor(&DstPtr,R,G,B,A);
00868                                         }
00869                                         SrcPtr += SrcXtraBytes;
00870                                         DstPtr += DstXtraBytes;
00871                                         AlphaPtr += AlphaXtra;
00872                                 }
00873 
00874                         return GE_TRUE;
00875                         }
00876 
00877                 }
00878                 else
00879                 {
00880                 uint32 DstColorKey;
00881 
00882                         ColorKey        = SrcInfo->ColorKey;
00883                         DstColorKey     = DstInfo->ColorKey;
00884 
00885                         assert(DstInfo->HasColorKey);
00886 
00887                         for(y=SizeY;y--;)
00888                         {
00889                                 for(x=SizeX;x--;)
00890                                 {
00891                                         SrcGetColor(&SrcPtr,&R,&G,&B,&A);
00892                                         A = *AlphaPtr++;
00893                                         if ( A < 128 )
00894                                         {
00895                                                 DstPutPixel(&DstPtr,DstColorKey);
00896                                         }
00897                                         else
00898                                         {
00899                                                 Pixel = DstComposePixel(R,G,B,255);
00900                                                 if ( Pixel == ColorKey )
00901                                                         Pixel ^= 1;
00902                                                 DstPutPixel(&DstPtr,Pixel);
00903                                         }
00904                                 }
00905                                 SrcPtr += SrcXtraBytes;
00906                                 DstPtr += DstXtraBytes;
00907                                 AlphaPtr += AlphaXtra;
00908                         }
00909 
00910                         return GE_TRUE;
00911                 }
00912         }
00913 
00914         assert("should not get here" == NULL);
00915 return GE_FALSE;
00916 // end Seperate Alpha conversions
00917 }
00918 
00919 /*}{*********************************************************************/
00920 
00921 geBoolean BlitData_ToSeparateAlpha(void)
00922 {
00923 geBitmap_Info AlphaInfo;
00924 void * AlphaData;
00925 uint8 *SrcPtr,*DstPtr,*AlphaPtr;
00926 int x,y,R,G,B,A;
00927 uint32 ColorKey,Pixel;
00928 int AlphaXtra;
00929 
00930         /*******
00931         **
00932                 support the extra Alpha Bmp
00933                 the common case is (4444) -> (8bit + 8bit)
00934 
00935                 we're pretty lazy about this; it's not optimized for speed
00936 
00937         **
00938          ******/
00939 
00940         SrcPtr = (uint8 *)SrcData;
00941         DstPtr = (uint8 *)DstData;
00942 
00943         if ( ! geBitmap_GetInfo(DstBmp->Alpha,&AlphaInfo,NULL) )
00944                 return GE_FALSE;
00945         if ( AlphaInfo.Format != GE_PIXELFORMAT_8BIT_GRAY )
00946         {
00947                 geErrorLog_AddString(-1,"Bitmap_BlitData : Alpha must be grayscale", NULL);
00948                 return GE_FALSE;
00949         }
00950 
00951         AlphaData = geBitmap_GetBits(DstBmp->Alpha);
00952         if ( ! AlphaData )
00953                 return GE_FALSE;
00954 
00955         AlphaPtr = (uint8 *)AlphaData;
00956         AlphaXtra = AlphaInfo.Stride - SizeX;
00957 
00958         if ( gePixelFormat_HasPalette(DstFormat) )
00959         {
00960                 // <>
00961                 geErrorLog_AddString(-1,"BlitData : doesn't support blit to palettized separates now", NULL);
00962                 // (alpha) -> pal + separate
00963                 //      requires palettization !!
00964                 return GE_FALSE;
00965         }
00966         else
00967         {
00968                 // this generic converter is pretty slow.
00969                 // fortunately genesis uses mostly the (Pal -> UnPal) conversion
00970                 // or the (Wavelet -> UnPal) conversion
00971 
00972                 assert( SrcOps->AMask && !(DstOps->AMask) );
00973 
00974                 if ( SrcPelBytes == 0 || DstPelBytes == 0 ) 
00975                 {
00976                         geErrorLog_AddString(-1,"Bitmap_BlitData : bad formats", NULL);
00977                         return GE_FALSE;
00978                 }
00979                 else if ( SrcInfo->HasColorKey && DstInfo->HasColorKey )
00980                 {
00981                 uint32 DstColorKey;
00982 
00983                         ColorKey = SrcInfo->ColorKey;
00984                         DstColorKey = DstInfo->ColorKey;
00985 
00986                         // with seperate alpha
00987 
00988                         for(y=SizeY;y--;)
00989                         {
00990                                 for(x=SizeX;x--;)
00991                                 {
00992                                         Pixel = SrcGetPixel(&SrcPtr);
00993                                         if ( Pixel == ColorKey )
00994                                         {
00995                                                 *AlphaPtr++ = 0;
00996                                                 DstPutPixel(&DstPtr,DstColorKey);
00997                                         }
00998                                         else
00999                                         {
01000                                                 SrcDecomposePixel(Pixel,&R,&G,&B,&A);
01001                                                 Pixel = DstComposePixel(R,G,B,255);
01002                                                 if ( Pixel == DstColorKey )     Pixel ^= 1;
01003                                                 DstPutPixel(&DstPtr,Pixel);
01004                                                 *AlphaPtr++ = A;
01005                                         }
01006                                 }
01007                                 SrcPtr += SrcXtraBytes;
01008                                 DstPtr += DstXtraBytes;
01009                                 AlphaPtr += AlphaXtra;
01010                         }
01011                 }
01012                 else if ( DstInfo->HasColorKey )
01013                 {
01014                         ColorKey = DstInfo->ColorKey;
01015 
01016                         // with seperate alpha
01017 
01018                         for(y=SizeY;y--;)
01019                         {
01020                                 for(x=SizeX;x--;)
01021                                 {
01022                                         SrcGetColor(&SrcPtr,&R,&G,&B,&A);
01023                                         Pixel = DstComposePixel(R,G,B,255);
01024                                         if ( Pixel == ColorKey ) Pixel ^= 1;
01025                                         *AlphaPtr++ = A;
01026                                         DstPutPixel(&DstPtr,Pixel);
01027                                 }
01028                                 SrcPtr += SrcXtraBytes;
01029                                 DstPtr += DstXtraBytes;
01030                                 AlphaPtr += AlphaXtra;
01031                         }
01032                 }
01033                 else if ( SrcInfo->HasColorKey )
01034                 {
01035                         // with seperate alpha
01036 
01037                         ColorKey = SrcInfo->ColorKey;
01038 
01039                         for(y=SizeY;y--;)
01040                         {
01041                                 for(x=SizeX;x--;)
01042                                 {
01043                                         Pixel = SrcGetPixel(&SrcPtr);
01044                                         if ( Pixel == ColorKey )
01045                                         {
01046                                                 *AlphaPtr++ = 0;
01047                                                 DstPutColor(&DstPtr,0,0,0,0);
01048                                         }
01049                                         else
01050                                         {
01051                                                 SrcDecomposePixel(Pixel,&R,&G,&B,&A);
01052                                                 DstPutColor(&DstPtr,R,G,B,255);
01053                                                 *AlphaPtr++ = A;
01054                                         }
01055                                 }
01056                                 SrcPtr += SrcXtraBytes;
01057                                 DstPtr += DstXtraBytes;
01058                                 AlphaPtr += AlphaXtra;
01059                         }
01060                 }
01061                 else
01062                 {
01063                         // with seperate alpha
01064                         for(y=SizeY;y--;)
01065                         {
01066                                 for(x=SizeX;x--;)
01067                                 {
01068                                         SrcGetColor(&SrcPtr,&R,&G,&B,&A);
01069                                         DstPutColor(&DstPtr,R,G,B,255);
01070                                         *AlphaPtr++ = A;
01071                                 }
01072                                 SrcPtr += SrcXtraBytes;
01073                                 DstPtr += DstXtraBytes;
01074                                 AlphaPtr += AlphaXtra;
01075                         }
01076                 }
01077 
01078                 assert( AlphaPtr        == (((uint8 *)AlphaData) + AlphaInfo.Stride * SizeY) );
01079                 assert( SrcPtr          == (((uint8 *)SrcData) + SrcRowBytes * SizeY ) );
01080                 assert( DstPtr          == (((uint8 *)DstData) + DstRowBytes * SizeY ) );
01081 
01082         return GE_TRUE;
01083         }
01084 
01085         // end Seperate Alpha conversions
01086 
01087 return GE_FALSE;
01088 }
01089 
01090 /*}{*********************************************************************/
01091 
01092 geBoolean BlitData_SameFormat(void)
01093 {
01094 char *SrcPtr,*DstPtr;
01095 gePixelFormat Format;
01096 
01097         Format = SrcFormat;
01098         SrcPtr = (char *)SrcData;
01099         DstPtr = (char *)DstData;
01100 
01101         if ( (!DstInfo->HasColorKey) || 
01102                         ( SrcInfo->HasColorKey && DstInfo->HasColorKey && SrcInfo->ColorKey == DstInfo->ColorKey ) )
01103         {
01104         int RowBytes,SrcStepBytes,DstStepBytes,y;
01105                 // just a mem-copy, with strides
01106                 
01107                 RowBytes = SizeX * SrcPelBytes;
01108                 SrcStepBytes = SrcXtraBytes + RowBytes;
01109                 DstStepBytes = DstXtraBytes + RowBytes;
01110                 for(y=SizeY;y--;)
01111                 {
01112                         memcpy( DstPtr, SrcPtr, RowBytes );
01113                         SrcPtr += SrcStepBytes;
01114                         DstPtr += DstStepBytes;
01115                 }
01116 
01117                 return GE_TRUE;
01118         }
01119         else // same format, different color key
01120         {
01121         int x,y;
01122         uint32 Pixel,DstColorKey;
01123 
01124                 //this is common
01125 
01126                 assert(DstInfo->HasColorKey);
01127                 DstColorKey = DstInfo->ColorKey;
01128                 
01129                 if ( SrcInfo->HasColorKey )
01130                 {
01131                 uint32 SrcColorKey ;
01132 
01133                         SrcColorKey = SrcInfo->ColorKey;
01134 
01135                         assert(SrcColorKey != DstColorKey);
01136                         
01137                         // start : formats same, source & dest have different color key
01138                         
01139                         switch(SrcPelBytes)
01140                         {
01141                                 default:
01142                                         return GE_FALSE;
01143                                 case 1:
01144                                 {
01145                                 uint8 *pSrc,*pDst;
01146                                         pSrc = (uint8 *)SrcPtr;
01147                                         pDst = (uint8 *)DstPtr;
01148 
01149                                         for(y=SizeY;y--;)
01150                                         {
01151                                                 for(x=SizeX;x--;)
01152                                                 {
01153                                                         Pixel = *pSrc++;
01154                                                         if ( Pixel == SrcColorKey )
01155                                                                 Pixel = DstColorKey;
01156                                                         else if ( Pixel == DstColorKey )
01157                                                                 Pixel = SrcColorKey;
01158                                                         *pDst++ = (uint8)Pixel;
01159                                                 }
01160                                                 pSrc += SrcXtra;
01161                                                 pDst += DstXtra;
01162                                         }
01163                                         return GE_TRUE;
01164                                 }
01165                                 case 2:
01166                                 {
01167                                 uint16 *pSrc,*pDst;
01168                                         pSrc = (uint16 *)SrcPtr;
01169                                         pDst = (uint16 *)DstPtr;
01170 
01171                                         for(y=SizeY;y--;)
01172                                         {
01173                                                 for(x=SizeX;x--;)
01174                                                 {
01175                                                         Pixel = *pSrc++;
01176                                                         if ( Pixel == SrcColorKey )
01177                                                                 Pixel = DstColorKey;
01178                                                         else if ( Pixel == DstColorKey )
01179                                                                 Pixel = SrcColorKey;
01180                                                         *pDst++ = (uint16)Pixel;
01181                                                 }
01182                                                 pSrc += SrcXtra;
01183                                                 pDst += DstXtra;
01184                                         }
01185                                         return GE_TRUE;
01186                                 }
01187                                 case 3:
01188                                 {
01189                                 uint8 *pSrc,*pDst;
01190                                         pSrc = (uint8 *)SrcPtr;
01191                                         pDst = (uint8 *)DstPtr;
01192 
01193                                         for(y=SizeY;y--;)
01194                                         {
01195                                                 for(x=SizeX;x--;)
01196                                                 {
01197                                                         Pixel = (pSrc[0]<<16) + (pSrc[1]<<8) + pSrc[2];
01198                                                         if ( Pixel == SrcColorKey )
01199                                                                 Pixel = DstColorKey;
01200                                                         else if ( Pixel == DstColorKey )
01201                                                                 Pixel = SrcColorKey;
01202                                                         pDst[0] = (uint8)(Pixel>>16);
01203                                                         pDst[1] = (uint8)((Pixel>>8)&0xFF);
01204                                                         pDst[2] = (uint8)(Pixel&0xFF);
01205                                                         pSrc += 3;
01206                                                         pDst += 3;
01207                                                 }
01208                                                 pSrc += SrcXtraBytes;
01209                                                 pDst += DstXtraBytes;
01210                                         }
01211                                         return GE_TRUE;
01212                                 }
01213                                 case 4:
01214                                 {
01215                                 uint32 *pSrc,*pDst;
01216                                         pSrc = (uint32 *)SrcPtr;
01217                                         pDst = (uint32 *)DstPtr;
01218 
01219                                         for(y=SizeY;y--;)
01220                                         {
01221                                                 for(x=SizeX;x--;)
01222                                                 {
01223                                                         Pixel = *pSrc++;
01224                                                         if ( Pixel == SrcColorKey )
01225                                                                 Pixel = DstColorKey;
01226                                                         else if ( Pixel == DstColorKey )
01227                                                                 Pixel = SrcColorKey;
01228                                                         *pDst++ = Pixel;
01229                                                 }
01230                                                 pSrc += SrcXtra;
01231                                                 pDst += DstXtra;
01232                                         }
01233                                         return GE_TRUE;
01234                                 }
01235                         }
01236 
01237                         // end : formats same, source & dest have different color key
01238                 }
01239                 else
01240                 {
01241                 
01242                         // start : formats same, dest had color key, source doesn't
01243 
01244                         switch(SrcPelBytes)
01245                         {
01246                                 default:
01247                                         return GE_FALSE;
01248                                 case 1:
01249                                 {
01250                                 uint8 *pSrc,*pDst;
01251                                         pSrc = (uint8 *)SrcPtr;
01252                                         pDst = (uint8 *)DstPtr;
01253 
01254                                         for(y=SizeY;y--;)
01255                                         {
01256                                                 for(x=SizeX;x--;)
01257                                                 {
01258                                                         Pixel = *pSrc++;
01259                                                         if ( Pixel == DstColorKey )
01260                                                                 Pixel ^= 1;
01261                                                         *pDst++ = (uint8)Pixel;
01262                                                 }
01263                                                 pSrc += SrcXtra;
01264                                                 pDst += DstXtra;
01265                                         }
01266                                         return GE_TRUE;
01267                                 }
01268                                 case 2:
01269                                 {
01270                                 uint16 *pSrc,*pDst;
01271                                         pSrc = (uint16 *)SrcPtr;
01272                                         pDst = (uint16 *)DstPtr;
01273 
01274                                         for(y=SizeY;y--;)
01275                                         {
01276                                                 for(x=SizeX;x--;)
01277                                                 {
01278                                                         Pixel = *pSrc++;
01279                                                         if ( Pixel == DstColorKey )
01280                                                                 Pixel ^= 1;
01281                                                         *pDst++ = (uint16)Pixel;
01282                                                 }
01283                                                 pSrc += SrcXtra;
01284                                                 pDst += DstXtra;
01285                                         }
01286                                         return GE_TRUE;
01287                                 }
01288                                 case 3:
01289                                 {
01290                                 uint8 *pSrc,*pDst;
01291                                         pSrc = (uint8 *)SrcPtr;
01292                                         pDst = (uint8 *)DstPtr;
01293 
01294                                         for(y=SizeY;y--;)
01295                                         {
01296                                                 for(x=SizeX;x--;)
01297                                                 {
01298                                                         Pixel = (pSrc[0]<<16) + (pSrc[1]<<8) + pSrc[2];
01299                                                         if ( Pixel == DstColorKey )
01300                                                                 Pixel ^= 1;
01301                                                         pDst[0] = (uint8)(Pixel>>16);
01302                                                         pDst[1] = (uint8)((Pixel>>8)&0xFF);
01303                                                         pDst[2] = (uint8)(Pixel&0xFF);
01304                                                         pSrc += 3;
01305                                                         pDst += 3;
01306                                                 }
01307                                                 pSrc += SrcXtraBytes;
01308                                                 pDst += DstXtraBytes;
01309                                         }
01310                                         return GE_TRUE;
01311                                 }
01312                                 case 4:
01313                                 {
01314                                 uint32 *pSrc,*pDst;
01315                                         pSrc = (uint32 *)SrcPtr;
01316                                         pDst = (uint32 *)DstPtr;
01317 
01318                                         for(y=SizeY;y--;)
01319                                         {
01320                                                 for(x=SizeX;x--;)
01321                                                 {
01322                                                         Pixel = *pSrc++;
01323                                                         if ( Pixel == DstColorKey )
01324                                                                 Pixel ^= 1;
01325                                                         *pDst++ = Pixel;
01326                                                 }
01327                                                 pSrc += SrcXtra;
01328                                                 pDst += DstXtra;
01329                                         }
01330                                         return GE_TRUE;
01331                                 }
01332                         }
01333                         
01334                         // end : formats same, dest had color key, source doesn't
01335                 }
01336 
01337                 return GE_TRUE;
01338         }
01339 // must have returned by now
01340 }
01341 /*}{*********************************************************************/
01342 
01343 geBoolean BlitData_DePalettize(void)
01344 {
01345         // pal -> unpal : easy
01346         if ( SrcFormat == GE_PIXELFORMAT_8BIT )
01347         {
01348         uint8 * SrcPtr;
01349         geBitmap_Palette * DstPal;
01350         int x,y,pal;
01351         const gePixelFormat_Operations *SrcOps,*DstOps;
01352 
01353                 x = y = pal = 0; //touch 'em
01354 
01355                 SrcOps = gePixelFormat_GetOperations(SrcPal->Format);
01356                 DstOps = gePixelFormat_GetOperations(DstFormat);
01357                 if ( ! SrcOps || ! DstOps )
01358                 {
01359                         return GE_FALSE;
01360                 }
01361 
01362                 // NO special cases
01363                 // just convert the Palette to the desired format, then do raw writes!
01364 
01365                 DstPal = geBitmap_Palette_Create(DstFormat,256);
01366                 if ( ! DstPal )
01367                 {
01368                         geErrorLog_AddString(-1,"Bitmap_BlitData : Palette_Create failed", NULL);       
01369                         return GE_FALSE;
01370                 }
01371 
01372                 // we do all alpha & colorkey by manipulating the DstPal lookup table !
01373 
01374                 //{} all these _geBitmap_Palette functions need failure checking
01375 
01376                 if ( ! geBitmap_Palette_Copy(SrcPal,DstPal) )
01377                 {
01378                         geErrorLog_AddString(-1,"Bitmap_BlitData : Palette_Copy failed", NULL);
01379                         geBitmap_Palette_Destroy(&DstPal);
01380                         return GE_FALSE;
01381                 }
01382 
01383                 if ( SrcInfo->HasColorKey )
01384                 {
01385                         if ( ! geBitmap_Palette_SetEntryColor(DstPal,SrcInfo->ColorKey,0,0,0,0) )
01386                         {
01387                                 geBitmap_Palette_Destroy(&DstPal);
01388                                 return GE_FALSE;
01389                         }
01390                 }
01391 
01392                 if ( DstInfo->HasColorKey ) // everything in genesis has colorkey!
01393                 {
01394                 int pal;
01395                 uint32 Pixel;
01396                         for(pal=0;pal<DstPal->Size;pal++)
01397                         {
01398                                 //{} all this GetEntry/SetEntry is awfully slow
01399                                 geBitmap_Palette_GetEntry(DstPal,pal,&Pixel);
01400                                 if ( Pixel == DstInfo->ColorKey )
01401                                 {
01402                                         geBitmap_Palette_SetEntry(DstPal,pal,Pixel^1);
01403                                 }
01404                         }
01405                         
01406                 }
01407 
01408                 if ( SrcInfo->HasColorKey && DstInfo->HasColorKey )
01409                 {
01410                         if ( ! geBitmap_Palette_SetEntry(DstPal,SrcInfo->ColorKey,DstInfo->ColorKey) )
01411                         {
01412                                 geBitmap_Palette_Destroy(&DstPal);
01413                                 return GE_FALSE;
01414                         }
01415                 }
01416 
01417                 if ( SrcOps->AMask && ! DstOps->AMask && DstInfo->HasColorKey )
01418                 {
01419                 int pal,R,G,B,A;
01420                 uint32 Pixel;
01421 
01422                         // if Src format has alpha & Dst format doesn't, turn it into color key
01423 
01424                         for(pal=0;pal<DstPal->Size;pal++)
01425                         {
01426                                 geBitmap_Palette_GetEntry(SrcPal,pal,&Pixel);
01427                                 if ( SrcInfo->HasColorKey && Pixel == SrcInfo->ColorKey )
01428                                 {
01429                                         A = 0;
01430                                 }
01431                                 else
01432                                 {
01433                                         gePixelFormat_DecomposePixel(SrcPal->Format,Pixel,&R,&G,&B,&A);
01434                                 }
01435                                 if ( A < ALPHA_TO_TRANSPARENCY_THRESHOLD )
01436                                         geBitmap_Palette_SetEntry(DstPal,pal,DstInfo->ColorKey);
01437                         }
01438                 }
01439 
01440                 SrcPtr = (uint8 *)SrcData;
01441 
01442                 // Pal -> UnPal loops : very common & very fast
01443 
01444                 switch( gePixelFormat_BytesPerPel(DstFormat) )
01445                 {
01446                         default:
01447                         {
01448                                 geBitmap_Palette_Destroy(&DstPal);
01449                                 return GE_FALSE;
01450                         }
01451                         case 1:
01452                         {
01453                         uint8 *DstPtr,*PalData;
01454                                 PalData = (uint8 *)DstPal->Data;
01455                                 DstPtr  = (uint8 *)DstData;
01456                                 for(y=SizeY;y--;)
01457                                 {
01458 
01459                                         #ifdef DONT_USE_ASM
01460 
01461                                         for(x=SizeX;x--;)
01462                                         {
01463                                                 pal = *SrcPtr++;
01464                                                 *DstPtr++ = PalData[pal];
01465                                         }
01466 
01467                                         #else
01468 
01469                                         #pragma message("Bitmap_Blitdata :using assembly DePalettize code")
01470                                         // {} is this minimal push safe in _fastcall ? aparently so!
01471 
01472                                         __asm
01473                                         {
01474                                                 push ebp
01475 
01476                                                 mov ecx,SizeX
01477                                                 mov esi,SrcPtr
01478                                                 mov edi,DstPtr
01479                                                 mov ebp,PalData
01480 
01481                                                 xor eax,eax
01482                                                 xor edx,edx
01483                                                 
01484                                         moredata1:
01485 
01486                                                 mov al, BYTE PTR [esi]
01487                                                 mov dl, BYTE PTR [ebp + eax]
01488                                                 mov BYTE PTR [edi], dl
01489 
01490                                                 inc esi
01491                                                 inc edi
01492                                                 dec ecx
01493 
01494                                                 jnz moredata1
01495 
01496                                                 pop ebp
01497                                         }
01498 
01499                                         SrcPtr += SizeX;
01500                                         DstPtr += SizeX;
01501 
01502                                         #endif
01503 
01504                                         SrcPtr += SrcXtra;
01505                                         DstPtr += DstXtra;
01506                                 }
01507                                 break;
01508                         }
01509                         case 2:
01510                         {
01511                         uint16 *DstPtr,*PalData;
01512 
01513                                 PalData = (uint16 *)DstPal->Data;
01514                                 DstPtr  = (uint16 *)DstData;
01515 
01516                         #ifdef DO_TIMER
01517                         {
01518                         #pragma message("Blitdata : doing timer")
01519                                 TIMER_VARS(WordCopy);
01520 
01521                                 timerFP = fopen("q:\\timer.log","at+");
01522                                 Timer_Start();
01523                                 TIMER_P(WordCopy);
01524                         #endif // DO_TIMER
01525 
01526                                 for(y=SizeY;y--;)
01527                                 {
01528                                         #ifdef DONT_USE_ASM
01529 
01530                                         for(x=SizeX;x--;)
01531                                         {
01532                                                 pal = *SrcPtr++;
01533                                                 *DstPtr++ = PalData[pal];
01534                                         }
01535 
01536                                         #else
01537 
01538                                         #if 1 // {
01539                                         if ( (SizeX&1) == 0 )
01540                                         {
01541                                                 assert( (((uint32)PalData)&3) == 0 );
01542                                                 assert( (((uint32)DstPtr )&3) == 0 );
01543 
01544                                                 // pair two pixels so we can output in dwords
01545                                                 
01546                                                 __asm
01547                                                 {
01548                                                         //pusha
01549                                                         push ebp
01550 
01551                                                         mov ecx,SizeX
01552                                                         mov esi,SrcPtr
01553                                                         mov edi,DstPtr
01554                                                         mov ebp,PalData
01555 
01556                                                         xor eax,eax
01557                                                         
01558                                                 moredata2_z:
01559 
01560                                                         //WordCopy : 0.000664 secs
01561                                                         //      about 12 clocks per pixel (!?)
01562 
01563                                                         // this is godly fast
01564 
01565                                                         movzx eax, BYTE PTR [esi+0]
01566                                                         movzx eax, WORD PTR [ebp + eax*2]
01567 
01568                                                         movzx edx, BYTE PTR [esi+1]
01569                                                         movzx edx, WORD PTR [ebp + edx*2]
01570                                                         shl edx,16
01571 
01572                                                         xor eax,edx
01573 
01574                                                         mov DWORD PTR [edi], eax
01575 
01576                                                         add esi,2
01577                                                         add edi,4
01578 
01579                                                         sub ecx,2
01580                                                         jnz moredata2_z
01581 
01582 #if 0 //{ 
01583                                                 // the old bad way:
01584                                                 // 0.000710 secs
01585                                                 moredata2_z:
01586 
01587                                                         //xor edx,edx   //xor edx,0 ; sneaky trick?
01588 
01589                                                         //mov al, BYTE PTR [esi]
01590                                                         movzx eax, BYTE PTR [esi]
01591                                                         inc esi
01592 
01593                                                         movzx edx, WORD PTR [ebp + eax*2]
01594                                                         //mov dx, WORD PTR [ebp + eax*2]
01595 
01596                                                         movzx eax, BYTE PTR [esi]
01597                                                         inc esi
01598 
01599                                                         // make room fo a new dx
01600                                                         //shl edx,16
01601                                                         //mov dx, WORD PTR [ebp + eax*2]        // !! STALL !! ; movzx eax, [] instead?
01602                                                         // byte order is wrong; fix with rol; 1 clock
01603                                                         //rol edx,16
01604 
01605                                                         movzx eax, WORD PTR [ebp + eax*2]       // can I do this?
01606                                                         shl eax,16
01607                                                         xor edx,eax
01608 
01609                                                         mov DWORD PTR [edi], edx
01610                                                         add edi,4
01611 
01612                                                         sub ecx,2
01613                                                         jnz moredata2_z
01614 #endif //}
01615 
01616                                                         pop ebp
01617                                                         //popa
01618                                                 }
01619 
01620                                         }
01621                                         else
01622                                         #endif //}
01623                                         {
01624 
01625                                                 __asm
01626                                                 {
01627                                                         //pusha
01628                                                         push ebp
01629 
01630                                                         mov ecx,SizeX
01631                                                         mov esi,SrcPtr
01632                                                         mov edi,DstPtr
01633                                                         mov ebp,PalData
01634 
01635                                                         xor eax,eax
01636                                                         xor edx,edx
01637                                                         
01638                                                 moredata2:
01639 
01640                                                         // about 14 clocks (!)
01641 
01642                                                         //mov al, BYTE PTR [esi]
01643                                                         movzx eax, BYTE PTR [esi]
01644                                                         //movzx edx, WORD PTR [ebp + eax*2]
01645                                                         mov dx, WORD PTR [ebp + eax*2]
01646                                                         mov WORD PTR [edi], dx
01647 
01648                                                         inc esi
01649                                                         add edi,2
01650 
01651                                                         dec ecx
01652                                                         jnz moredata2
01653 
01654                                                         pop ebp
01655                                                         //popa
01656                                                 }
01657                                         }
01658 
01659                                         SrcPtr += SizeX;
01660                                         DstPtr += SizeX;
01661 
01662                                         #endif
01663 
01664                                         SrcPtr += SrcXtra;
01665                                         DstPtr += DstXtra;
01666                                 }
01667 
01668                                 #ifdef DO_TIMER
01669                                 TIMER_Q(WordCopy);
01670                                 TIMER_COUNT();
01671                                 Timer_Stop();
01672                                 if ( timerFP )
01673                                 {
01674                                         TIMER_REPORT(WordCopy);
01675                                 }
01676                         }
01677                         #endif
01678 
01679                                 // C , Debug :
01680                                 //WordCopy             : 0.001243 : 99.4 %
01681                                 // asm paired : mov al,
01682                                 //WordCopy             : 0.000858 : 99.1 %
01683                                 // asm paired : movzx eax,
01684                                 //WordCopy             : 0.000798 : 98.9 %
01685                                 // asm paired : with xor edx,0 & movzx edx,
01686                                 //WordCopy             : 0.000903 : 99.2 %
01687                                 // asm paired : with xor edx,0 & mov dx,
01688                                 //WordCopy             : 0.000941 : 99.4 %
01689                                 // asm : not paired 
01690                                 //WordCopy             : 0.000765 : 98.8 %
01691                                 // asm : paired, using xor edx,eax !
01692                                 //WordCopy             : 0.000710 : 98.9 %
01693 
01694                                 break;
01695                         }
01696                         case 3:
01697                         {
01698                         uint8 *DstPtr,*PalData;
01699                                 PalData = (uint8 *)DstPal->Data;
01700                                 DstPtr  = (uint8 *)DstData;
01701 
01702 //                              pushTSC();
01703 
01704                                 for(y=SizeY;y--;)
01705                                 {
01706 
01707                                         #ifdef DONT_USE_ASM
01708                                         {
01709                                         uint8 *PalPtr;
01710 
01711                                                 for(x=SizeX;x--;)
01712                                                 {
01713                                                         pal = *SrcPtr++;
01714                                                         PalPtr = PalData + (3*pal);
01715                                                         *DstPtr++ = *PalPtr++;
01716                                                         *DstPtr++ = *PalPtr++;
01717                                                         *DstPtr++ = *PalPtr;
01718                                                 }
01719 
01720                                         }
01721                                         #else
01722 
01723                                         __asm
01724                                         {
01725                                                 push ebp
01726 
01727                                                 mov ecx,SizeX
01728                                                 mov esi,SrcPtr
01729                                                 mov edi,DstPtr
01730                                                 mov ebp,PalData
01731 
01732                                                 xor eax,eax
01733                                                 xor edx,edx
01734                                                 
01735                                         moredata3:
01736 
01737                                                 movzx eax, BYTE PTR [esi]
01738                                                 inc esi
01739 
01740                                                 imul eax,3
01741                                                 add eax,ebp
01742                                                 mov dl, BYTE PTR [eax]
01743                                                 mov BYTE PTR [edi], dl
01744                                                 inc edi
01745                                                 mov dl, BYTE PTR [eax + 1]
01746                                                 mov BYTE PTR [edi], dl
01747                                                 inc edi
01748                                                 mov dl, BYTE PTR [eax + 2]
01749                                                 mov BYTE PTR [edi], dl
01750                                                 inc edi
01751 
01752                                                 dec ecx
01753                                                 jnz moredata3
01754 
01755                                                 pop ebp
01756                                         }
01757 
01758                                         SrcPtr += SizeX;
01759                                         DstPtr += SizeX*3;
01760 
01761                                         #endif
01762 
01763                                         SrcPtr += SrcXtra;
01764                                         DstPtr += DstXtra;
01765                                 }
01766                                 
01767 //                              showPopTSCper("depal 24bit",SizeX*SizeY,"pixel");
01768 
01769                                 break;
01770                         }
01771                         case 4:
01772                         {
01773                         uint32 *DstPtr,*PalData;
01774                                 PalData = (uint32 *)DstPal->Data;
01775                                 DstPtr  = (uint32 *)DstData;
01776                                 for(y=SizeY;y--;)
01777                                 {
01778                                         #ifdef DONT_USE_ASM
01779 
01780                                         for(x=SizeX;x--;)
01781                                         {
01782                                                 pal = *SrcPtr++;
01783                                                 *DstPtr++ = PalData[pal];
01784                                         }
01785 
01786                                         #else
01787 
01788                                         assert( (((uint32)PalData)&3) == 0);
01789                                         assert( (((uint32)DstPtr)&3) == 0);
01790 
01791                                         __asm
01792                                         {
01793                                                 push ebp
01794 
01795                                                 mov ecx,SizeX
01796                                                 mov esi,SrcPtr
01797                                                 mov edi,DstPtr
01798                                                 mov ebp,PalData
01799 
01800                                                 xor eax,eax
01801                                                 
01802                                         moredata4:
01803 
01804                                                 mov al, BYTE PTR [esi]
01805                                                 mov edx, DWORD PTR [ebp + eax*4]
01806                                                 mov DWORD PTR [edi], edx
01807 
01808                                                 inc esi
01809                                                 add edi,4
01810 
01811                                                 dec ecx
01812                                                 jnz moredata4
01813 
01814                                                 pop ebp
01815                                         }
01816 
01817                                         SrcPtr += SizeX;
01818                                         DstPtr += SizeX;
01819 
01820                                         #endif
01821 
01822                                         SrcPtr += SrcXtra;
01823                                         DstPtr += DstXtra;
01824                                 }
01825                                 break;
01826                         }
01827                 }
01828 
01829                 geBitmap_Palette_Destroy(&DstPal);
01830 
01831                 return GE_TRUE;
01832         }
01833 return GE_FALSE;
01834 }
01835 
01836 /*}{*********************************************************************/
01837 
01838 geBoolean BlitData_Palettize(void)
01839 {
01840         // unpal -> pal : hard
01841 return palettizePlane(  SrcInfo,SrcData,
01842                                                 DstInfo,DstData,
01843                                                 SizeX,SizeY);
01844 }
01845 
01846 /*}{*********************************************************************/
01847 

Generated on Tue Sep 30 12:35:18 2003 for GTestAndEngine by doxygen 1.3.2