00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052 #include <math.h>
00053 #include <time.h>
00054 #include <stdio.h>
00055 #include <assert.h>
00056 #include <stdlib.h>
00057 #include <string.h>
00058
00059 #include "basetype.h"
00060 #include "getypes.h"
00061 #include "ram.h"
00062
00063 #include "vfile.h"
00064 #include "ErrorLog.h"
00065 #include "Log.h"
00066 #include "mempool.h"
00067
00068 #include "bitmap.h"
00069 #include "bitmap._h"
00070 #include "bitmap.__h"
00071 #include "bitmap_blitdata.h"
00072 #include "bitmap_gamma.h"
00073
00074 #include "palcreate.h"
00075 #include "palettize.h"
00076
00077 #ifdef DO_TIMER
00078 #include "timer.h"
00079 #endif
00080
00081 #define allocate(ptr) ptr = geRam_Allocate(sizeof(*ptr))
00082 #define clear(ptr) memset(ptr,0,sizeof(*ptr))
00083
00084 #define SHIFT_R_ROUNDUP(val,shift) (((val)+(1<<(shift)) - 1)>>(shift))
00085
00086
00087
00088
00089
00090
00091
00092 #ifdef _DEBUG
00093 #define Debug(x) x
00094 static int _Bitmap_Debug_ActiveCount = 0;
00095 static int _Bitmap_Debug_ActiveRefs = 0;
00096 #else
00097 #define Debug(x)
00098 #endif
00099
00100 static int BitmapInit_RefCount = 0;
00101 static MemPool * BitmapPool = NULL;
00102
00103 void geBitmap_Start(void)
00104 {
00105 if ( BitmapInit_RefCount == 0 )
00106 {
00107 BitmapPool = MemPool_Create(sizeof(geBitmap),100,100);
00108 assert(BitmapPool);
00109 Palettize_Start();
00110 PalCreate_Start();
00111 }
00112 BitmapInit_RefCount ++;
00113 }
00114
00115 void geBitmap_Stop(void)
00116 {
00117 assert(BitmapInit_RefCount > 0 );
00118 BitmapInit_RefCount --;
00119 if ( BitmapInit_RefCount == 0 )
00120 {
00121 assert(BitmapPool);
00122 MemPool_Destroy(&BitmapPool);
00123 Palettize_Stop();
00124 PalCreate_Stop();
00125 }
00126 }
00127
00128
00129
00130 geBitmap * geBitmap_Create_Base(void)
00131 {
00132 geBitmap * Bmp;
00133
00134 geBitmap_Start();
00135
00136 Bmp = MemPool_GetHunk(BitmapPool);
00137
00138 Bmp->RefCount = 1;
00139
00140 Bmp->DriverGamma = Bmp->DriverGammaLast = 1.0f;
00141
00142 Debug(_Bitmap_Debug_ActiveRefs ++);
00143 Debug(_Bitmap_Debug_ActiveCount ++);
00144
00145 return Bmp;
00146 }
00147
00148 void geBitmap_Destroy_Base(geBitmap *Bmp)
00149 {
00150 assert(Bmp);
00151 assert(Bmp->RefCount == 0);
00152 Debug(_Bitmap_Debug_ActiveCount --);
00153
00154 MemPool_FreeHunk(BitmapPool,Bmp);
00155
00156 geBitmap_Stop();
00157 }
00158
00159 GENESISAPI void GENESISCC geBitmap_CreateRef(geBitmap *Bmp)
00160 {
00161 assert(Bmp);
00162 Bmp->RefCount ++;
00163 Debug(_Bitmap_Debug_ActiveRefs ++);
00164 }
00165
00166 GENESISAPI geBitmap * GENESISCC geBitmap_Create(
00167 int Width,
00168 int Height,
00169 int MipCount,
00170 gePixelFormat Format)
00171 {
00172 geBitmap * Bmp;
00173
00174 Bmp = geBitmap_Create_Base();
00175 if ( ! Bmp )
00176 return NULL;
00177
00178 assert( Width > 0 );
00179 assert( Height > 0 );
00180 if ( MipCount == 0 )
00181 MipCount = 1;
00182 assert( MipCount > 0 );
00183
00184 Bmp->Info.Width = Width;
00185 Bmp->Info.Stride = Width;
00186 Bmp->Info.Height = Height;
00187 Bmp->Info.Format = Format;
00188
00189 Bmp->Info.MinimumMip = 0;
00190 Bmp->Info.MaximumMip = 0;
00191 Bmp->Info.HasColorKey = GE_FALSE;
00192
00193 Bmp->SeekMipCount = MipCount;
00194
00195 if ( Format == GE_PIXELFORMAT_WAVELET )
00196 {
00197 geErrorLog_AddString(-1,"Genesis3D 1.0 does not support Wavelet Images",NULL);
00198 return NULL;
00199 }
00200
00201 return Bmp;
00202 }
00203
00204 GENESISAPI geBitmap * GENESISCC geBitmap_CreateFromInfo(const geBitmap_Info * pInfo)
00205 {
00206 geBitmap * Bmp;
00207
00208 assert(pInfo);
00209 assert(geBitmap_Info_IsValid(pInfo));
00210
00211 Bmp = geBitmap_Create_Base();
00212 if ( ! Bmp )
00213 return NULL;
00214
00215 Bmp->Info = *pInfo;
00216
00217 if ( Bmp->Info.Stride < Bmp->Info.Width )
00218 Bmp->Info.Stride = Bmp->Info.Width;
00219
00220 if ( Bmp->Info.Palette )
00221 geBitmap_Palette_CreateRef(Bmp->Info.Palette);
00222
00223 if ( Bmp->Info.Format == GE_PIXELFORMAT_WAVELET )
00224 {
00225 geErrorLog_AddString(-1,"Genesis3D 1.0 does not support Wavelet Images",NULL);
00226 return NULL;
00227 }
00228
00229 return Bmp;
00230 }
00231
00232 GENESISAPI geBoolean GENESISCC geBitmap_Destroy(geBitmap **Bmp)
00233 {
00234 int i;
00235 geBitmap * Bitmap;
00236
00237 assert(Bmp);
00238
00239 Bitmap = *Bmp;
00240
00241 if ( Bitmap )
00242 {
00243 if ( Bitmap->LockOwner )
00244 {
00245 return geBitmap_UnLock(Bitmap);
00246 }
00247
00248 if ( Bitmap->RefCount <= 1 )
00249 {
00250 if ( Bitmap->DataOwner )
00251 {
00252 geBitmap_Destroy(&(Bitmap->DataOwner));
00253 Bitmap->DataOwner = NULL;
00254 }
00255 else
00256 {
00257 if ( Bitmap->Driver )
00258 {
00259 geBitmap_DetachDriver(Bitmap,GE_FALSE);
00260 }
00261
00262 for (i = Bitmap->Info.MinimumMip; i <= Bitmap->Info.MaximumMip; i++)
00263 {
00264 if (Bitmap->Data[i])
00265 geRam_Free(Bitmap->Data[i]);
00266 }
00267 }
00268 }
00269
00270 Debug(assert(_Bitmap_Debug_ActiveRefs > 0));
00271 Debug(_Bitmap_Debug_ActiveRefs --);
00272
00273 Bitmap->RefCount --;
00274
00275 if ( Bitmap->RefCount <= 0 )
00276 {
00277 if (Bitmap->Alpha)
00278 {
00279 geBitmap_Destroy(&Bitmap->Alpha);
00280 }
00281
00282 if (Bitmap->Info.Palette)
00283 {
00284 geBitmap_Palette_Destroy(&(Bitmap->Info.Palette));
00285 }
00286
00287 if (Bitmap->DriverInfo.Palette)
00288 {
00289 geBitmap_Palette_Destroy(&(Bitmap->DriverInfo.Palette));
00290 }
00291
00292 geBitmap_Destroy_Base(Bitmap);
00293
00294 *Bmp = NULL;
00295
00296 return GE_TRUE;
00297 }
00298 }
00299
00300 return GE_FALSE;
00301 }
00302
00303 geBoolean geBitmap_AllocSystemMip(geBitmap *Bmp,int mip)
00304 {
00305 if ( ! Bmp )
00306 {
00307 return GE_FALSE;
00308 }
00309
00310 if ( Bmp->LockOwner && mip != 0 ) return GE_FALSE;
00311
00312 if ( ! Bmp->Data[mip] )
00313 {
00314 int bytes;
00315 bytes = geBitmap_MipBytes(Bmp,mip);
00316 if ( bytes == 0 )
00317 {
00318 Bmp->Data[mip] = NULL;
00319 return GE_TRUE;
00320 }
00321 Bmp->Data[mip] = geRam_Allocate( bytes );
00322 }
00323
00324 return (Bmp->Data[mip]) ? GE_TRUE : GE_FALSE;
00325 }
00326
00327 geBoolean geBitmap_AllocPalette(geBitmap *Bmp,gePixelFormat Format,DRV_Driver * Driver)
00328 {
00329 geBitmap_Info * BmpInfo;
00330 assert(Bmp);
00331
00332 if ( Driver )
00333 BmpInfo = &(Bmp->DriverInfo);
00334 else
00335 BmpInfo = &(Bmp->Info);
00336
00337 if ( ! gePixelFormat_IsRaw(Format) )
00338 Format = GE_PIXELFORMAT_32BIT_XRGB;
00339
00340 if ( ! BmpInfo->Palette )
00341 {
00342 assert( BmpInfo->Format == GE_PIXELFORMAT_8BIT_PAL );
00343
00344 if ( Driver )
00345 {
00346 geBoolean BmpHasAlpha;
00347
00348 BmpHasAlpha = GE_FALSE;
00349 if ( gePixelFormat_HasGoodAlpha(Bmp->Info.Format) )
00350 BmpHasAlpha = GE_TRUE;
00351 else if ( Bmp->Info.Palette && gePixelFormat_HasGoodAlpha(Bmp->Info.Palette->Format) )
00352 BmpHasAlpha = GE_TRUE;
00353
00354 if ( BmpHasAlpha || (Bmp->Info.HasColorKey && ! Bmp->DriverInfo.HasColorKey ) )
00355 Format = GE_PIXELFORMAT_32BIT_ARGB;
00356
00357 BmpInfo->Palette = geBitmap_Palette_CreateFromDriver(Driver,Format,256);
00358 }
00359 else
00360 {
00361 BmpInfo->Palette = geBitmap_Palette_Create(Format,256);
00362 }
00363 }
00364
00365 if ( ! BmpInfo->Palette )
00366 return GE_FALSE;
00367
00368 if ( BmpInfo->HasColorKey )
00369 {
00370 if ( ! BmpInfo->Palette->HasColorKey )
00371 {
00372 BmpInfo->Palette->HasColorKey = GE_TRUE;
00373 BmpInfo->Palette->ColorKey = 1;
00374 }
00375 BmpInfo->Palette->ColorKeyIndex = BmpInfo->ColorKey;
00376 }
00377
00378 if ( Driver )
00379 {
00380 assert( Bmp->DriverHandle );
00381 assert( BmpInfo->Palette->DriverHandle );
00382 if ( ! Driver->THandle_SetPalette(Bmp->DriverHandle,BmpInfo->Palette->DriverHandle) )
00383 {
00384 geErrorLog_AddString(-1,"AllocPal : THandle_SetPalette", NULL);
00385 return GE_FALSE;
00386 }
00387 }
00388
00389 if ( ! Bmp->Info.Palette )
00390 {
00391 Bmp->Info.Palette = geBitmap_Palette_CreateCopy(BmpInfo->Palette);
00392 }
00393
00394 return GE_TRUE;
00395 }
00396
00397
00398
00399 GENESISAPI geBoolean GENESISCC geBitmap_LockForWrite(
00400 geBitmap * Bmp,
00401 geBitmap ** Target,
00402 int MinimumMip,
00403 int MaximumMip)
00404 {
00405 int mip;
00406
00407 assert( geBitmap_IsValid(Bmp) );
00408 assert( Target);
00409 assert(MaximumMip >= MinimumMip);
00410 assert( &Bmp != Target );
00411
00412 if ( Bmp->LockCount || Bmp->LockOwner )
00413 {
00414 geErrorLog_AddString(-1,"LockForWrite : already locked", NULL);
00415 return GE_FALSE;
00416 }
00417
00418 if ( Bmp->DriverHandle )
00419 {
00420 if ( (MinimumMip < Bmp->DriverInfo.MinimumMip) ||
00421 (MaximumMip > Bmp->DriverInfo.MaximumMip) )
00422 {
00423 geErrorLog_AddString(-1,"LockForWrite : Driver : invalid mip", NULL);
00424 return GE_FALSE;
00425 }
00426 }
00427 else
00428 {
00429 if ( (MinimumMip < Bmp->Info.MinimumMip) ||
00430 (MaximumMip >= MAXMIPLEVELS) )
00431 {
00432 geErrorLog_AddString(-1,"LockForWrite : System : invalid mip", NULL);
00433 return GE_FALSE;
00434 }
00435
00436 if ( MaximumMip > Bmp->Info.MaximumMip )
00437 {
00438 if ( ! geBitmap_MakeSystemMips(Bmp,Bmp->Info.MaximumMip,MaximumMip) )
00439 return GE_FALSE;
00440 Bmp->Info.MaximumMip = MaximumMip;
00441 }
00442 }
00443
00444 for(mip=MinimumMip;mip <= MaximumMip;mip ++)
00445 {
00446 if ( Bmp->DriverHandle )
00447 {
00448 Target[ mip - MinimumMip ] = geBitmap_CreateLockFromMipOnDriver(Bmp,mip,-1);
00449 }
00450 else
00451 {
00452 Target[ mip - MinimumMip ] = geBitmap_CreateLockFromMipSystem(Bmp,mip,-1);
00453 }
00454 if ( ! Target[ mip - MinimumMip ] )
00455 {
00456 geErrorLog_AddString(-1,"LockForWrite : CreateLockFromMip failed", NULL);
00457 mip--;
00458 while(mip >= MinimumMip )
00459 {
00460 geBitmap_Destroy( & Target[ mip - MinimumMip ] );
00461 mip--;
00462 }
00463 return GE_FALSE;
00464 }
00465 }
00466
00467 assert( Bmp->LockCount == - (MaximumMip - MinimumMip + 1) );
00468
00469 return GE_TRUE;
00470 }
00471
00472 GENESISAPI geBoolean GENESISCC geBitmap_LockForWriteFormat(
00473 geBitmap * Bmp,
00474 geBitmap ** Target,
00475 int MinimumMip,
00476 int MaximumMip,
00477 gePixelFormat Format)
00478 {
00479 int mip;
00480
00481 assert( geBitmap_IsValid(Bmp) );
00482 assert( Target);
00483 assert(MaximumMip >= MinimumMip);
00484 assert( &Bmp != Target );
00485
00486 if ( Bmp->LockCount || Bmp->LockOwner )
00487 {
00488 geErrorLog_AddString(-1,"LockForWrite : already locked", NULL);
00489 return GE_FALSE;
00490 }
00491
00492 if ( Format != Bmp->Info.Format && Format != Bmp->DriverInfo.Format )
00493 {
00494 geErrorLog_AddString(-1,"LockForWriteFormat : must be System or Driver Format !", NULL);
00495 return GE_FALSE;
00496 }
00497
00498 if ( Format == Bmp->DriverInfo.Format )
00499 {
00500 if ( MinimumMip < Bmp->DriverInfo.MinimumMip || MaximumMip > Bmp->DriverInfo.MaximumMip )
00501 {
00502 geErrorLog_AddString(-1,"LockForWrite : invalid Driver mip", NULL);
00503 return GE_FALSE;
00504 }
00505 }
00506 else
00507 {
00508 assert( Format == Bmp->Info.Format );
00509
00510 if ( Bmp->DriverHandle )
00511 {
00512 if ( ! geBitmap_Update_DriverToSystem(Bmp) )
00513 {
00514 geErrorLog_AddString(-1,"LockForWrite : Update_DriverToSystem", NULL);
00515 return GE_FALSE;
00516 }
00517 }
00518
00519
00520
00521 if ( MinimumMip < Bmp->Info.MinimumMip || MaximumMip >= MAXMIPLEVELS )
00522 {
00523 geErrorLog_AddString(-1,"LockForWrite : invalid System mip", NULL);
00524 return GE_FALSE;
00525 }
00526
00527 if ( ! geBitmap_MakeSystemMips(Bmp,Bmp->Info.MaximumMip,MaximumMip) )
00528 return GE_FALSE;
00529 Bmp->Info.MaximumMip = MaximumMip;
00530 }
00531
00532 for(mip=MinimumMip;mip <= MaximumMip;mip ++)
00533 {
00534 if ( Bmp->DriverHandle && Format == Bmp->DriverInfo.Format )
00535 {
00536 Target[ mip - MinimumMip ] = geBitmap_CreateLockFromMipOnDriver(Bmp,mip,-1);
00537 }
00538 else
00539 {
00540 Target[ mip - MinimumMip ] = geBitmap_CreateLockFromMipSystem(Bmp,mip,-1);
00541 }
00542
00543 if ( ! Target[ mip - MinimumMip ] )
00544 {
00545 geErrorLog_AddString(-1,"LockForWrite : CreateLockFromMip failed", NULL);
00546 mip--;
00547 while(mip >= MinimumMip )
00548 {
00549 geBitmap_Destroy( & Target[ mip - MinimumMip ] );
00550 mip--;
00551 }
00552 return GE_FALSE;
00553 }
00554 }
00555
00556 assert( Bmp->LockCount == - (MaximumMip - MinimumMip + 1) );
00557
00558 return GE_TRUE;
00559 }
00560
00561 GENESISAPI geBoolean GENESISCC geBitmap_LockForReadNative(
00562 const geBitmap * iBmp,
00563 geBitmap ** Target,
00564 int MinimumMip,
00565 int MaximumMip)
00566 {
00567 int mip;
00568 geBitmap * Bmp = (geBitmap *)iBmp;
00569
00570 assert( geBitmap_IsValid(Bmp) );
00571 assert( Target);
00572 assert(MaximumMip >= MinimumMip);
00573 assert( &Bmp != Target );
00574
00575 if ( (MinimumMip < Bmp->Info.MinimumMip && MinimumMip < Bmp->DriverInfo.MinimumMip) ||
00576 (MaximumMip >= MAXMIPLEVELS) )
00577 {
00578 geErrorLog_AddString(-1,"LockForRead : invalid mip", NULL);
00579 return GE_FALSE;
00580 }
00581
00582 if ( Bmp->LockCount < 0 || Bmp->LockOwner )
00583 {
00584 geErrorLog_AddString(-1,"LockForRead : already locked", NULL);
00585 return GE_FALSE;
00586 }
00587
00588 for(mip=MinimumMip;mip <= MaximumMip;mip ++)
00589 {
00590
00591 if ( Bmp->DriverHandle && Bmp->DriverDataChanged
00592 && mip <= Bmp->DriverInfo.MaximumMip && mip >= Bmp->DriverInfo.MinimumMip)
00593 {
00594 Target[ mip - MinimumMip ] = geBitmap_CreateLockFromMipOnDriver(Bmp,mip,1);
00595 }
00596 else
00597 {
00598 Target[ mip - MinimumMip ] = geBitmap_CreateLockFromMipSystem(Bmp,mip,1);
00599 }
00600 if ( ! Target[ mip - MinimumMip ] )
00601 {
00602 geErrorLog_AddString(-1,"LockForRead : CreateLockFromMip failed", NULL);
00603 mip--;
00604 while(mip >= MinimumMip )
00605 {
00606 geBitmap_Destroy( & Target[ mip - MinimumMip ] );
00607 mip--;
00608 }
00609 return GE_FALSE;
00610 }
00611 }
00612
00613 return GE_TRUE;
00614 }
00615
00616 GENESISAPI geBoolean GENESISCC geBitmap_LockForRead(
00617 const geBitmap * iBmp,
00618 geBitmap ** Target,
00619 int MinimumMip,
00620 int MaximumMip,
00621 gePixelFormat Format,
00622 geBoolean HasColorKey,
00623 uint32 ColorKey)
00624 {
00625 int mip;
00626 geBitmap * Bmp = (geBitmap *)iBmp;
00627
00628 assert( geBitmap_IsValid(Bmp) );
00629 assert( Target);
00630 assert(MaximumMip >= MinimumMip);
00631 assert( &Bmp != Target );
00632
00633 if ( MinimumMip < Bmp->Info.MinimumMip ||
00634
00635 MaximumMip >= MAXMIPLEVELS )
00636 {
00637 geErrorLog_AddString(-1,"LockForRead : invalid mip", NULL);
00638 return GE_FALSE;
00639 }
00640
00641 if ( Bmp->LockCount < 0 || Bmp->LockOwner )
00642 {
00643 geErrorLog_AddString(-1,"LockForRead : already locked", NULL);
00644 return GE_FALSE;
00645 }
00646
00647 for(mip=MinimumMip;mip <= MaximumMip;mip ++)
00648 {
00649 Target[ mip - MinimumMip ] = geBitmap_CreateLockFromMip(Bmp,mip, Format,HasColorKey,ColorKey,1);
00650 if ( ! Target[ mip - MinimumMip ] )
00651 {
00652 geErrorLog_AddString(-1,"LockForRead : CreateLockFromMip failed", NULL);
00653 mip--;
00654 while(mip >= MinimumMip )
00655 {
00656 geBitmap_Destroy( & Target[ mip - MinimumMip ] );
00657 mip--;
00658 }
00659 return GE_FALSE;
00660 }
00661 }
00662
00663 return GE_TRUE;
00664 }
00665
00666 geBoolean geBitmap_UnLockArray_NoChange(geBitmap **Locks,int Size)
00667 {
00668 int i;
00669 geBoolean Ret = GE_TRUE;
00670 assert(Locks);
00671 for(i=0;i<Size;i++)
00672 {
00673 if ( ! geBitmap_UnLock_NoChange(Locks[i]) )
00674 Ret = GE_FALSE;
00675 }
00676 return Ret;
00677 }
00678
00679 GENESISAPI geBoolean GENESISCC geBitmap_UnLockArray(geBitmap **Locks,int Size)
00680 {
00681 int i;
00682 geBoolean Ret = GE_TRUE;
00683 assert(Locks);
00684 for(i=0;i<Size;i++)
00685 {
00686 if ( ! geBitmap_UnLock(Locks[i]) )
00687 Ret = GE_FALSE;
00688 }
00689 return Ret;
00690 }
00691
00692 geBoolean geBitmap_UnLock_Internal(geBitmap *Bmp,geBoolean Apply)
00693 {
00694 geBoolean Ret = GE_TRUE;
00695
00696 if ( ! Bmp )
00697 {
00698 geErrorLog_AddString(-1,"UnLock : bad bmp", NULL);
00699 return GE_FALSE;
00700 }
00701
00702 assert( Bmp->LockCount == 0 );
00703
00704 if ( Bmp->LockOwner )
00705 {
00706 int DoUpdate = 0;
00707
00708 assert(Bmp->LockOwner->LockCount != 0);
00709 if ( Bmp->LockOwner->LockCount > 0 )
00710 {
00711 Bmp->LockOwner->LockCount --;
00712 }
00713 else if ( Bmp->LockOwner->LockCount < 0 )
00714 {
00715 Bmp->LockOwner->LockCount ++;
00716
00717 if ( Apply )
00718 {
00719 geBitmap_Palette * Pal;
00720
00721 Bmp->LockOwner->Modified[Bmp->Info.MinimumMip] = GE_TRUE;
00722
00723 Pal = Bmp->DriverInfo.Palette ? Bmp->DriverInfo.Palette : Bmp->Info.Palette;
00724 if ( Pal )
00725 geBitmap_SetPalette(Bmp->LockOwner,Pal);
00726
00727
00728 }
00729
00730 if ( Bmp->LockOwner->LockCount == 0 && Apply )
00731 {
00732
00733
00734 if ( Bmp->DriverBitsLocked )
00735 {
00736 assert( Bmp->DriverHandle );
00737 Bmp->LockOwner->DriverDataChanged = GE_TRUE;
00738 DoUpdate = 1;
00739 }
00740 else
00741 {
00742 DoUpdate = -1;
00743 }
00744 }
00745 }
00746
00747 if ( Bmp->DriverHandle && Bmp->DriverBitsLocked )
00748 {
00749 assert(Bmp->Driver);
00750 if ( ! Bmp->Driver->THandle_UnLock(Bmp->DriverHandle, Bmp->DriverMipLock) )
00751 {
00752 geErrorLog_AddString(-1,"UnLock : thandle_unlock", NULL);
00753 Ret = GE_FALSE;
00754 }
00755 Bmp->DriverBitsLocked = GE_FALSE;
00756 Bmp->DriverMipLock = 0;
00757 }
00758
00759 if ( Bmp->Alpha )
00760 {
00761 if ( ! geBitmap_UnLock(Bmp->Alpha) )
00762 Ret = GE_FALSE;
00763
00764 Bmp->Alpha = NULL;
00765 }
00766
00767 if ( DoUpdate )
00768 {
00769 assert(Bmp->LockOwner->LockCount == 0 );
00770
00771 if ( DoUpdate > 0 )
00772 {
00773
00774
00775
00776
00777 }
00778 else
00779 {
00780 if ( Bmp->LockOwner->DriverHandle )
00781 if ( ! geBitmap_Update_SystemToDriver(Bmp->LockOwner) )
00782 Ret = GE_FALSE;
00783 }
00784 }
00785
00786
00787 geBitmap_Destroy(&(Bmp->LockOwner));
00788 Bmp->LockOwner = NULL;
00789
00790 }
00791
00792
00793 assert(Bmp->RefCount == 1);
00794
00795 geBitmap_Destroy(&Bmp);
00796
00797 assert(Bmp == NULL);
00798
00799 return Ret;
00800 }
00801
00802 GENESISAPI geBoolean GENESISCC geBitmap_UnLock(geBitmap *Bmp)
00803 {
00804 return geBitmap_UnLock_Internal(Bmp,GE_TRUE);
00805 }
00806
00807 geBoolean geBitmap_UnLock_NoChange(geBitmap *Bmp)
00808 {
00809 return geBitmap_UnLock_Internal(Bmp,GE_FALSE);
00810 }
00811
00812 GENESISAPI void * GENESISCC geBitmap_GetBits(geBitmap *Bmp)
00813 {
00814 void * bits;
00815
00816 assert( geBitmap_IsValid(Bmp) );
00817
00818 if ( ! Bmp )
00819 {
00820 geErrorLog_AddString(-1,"GetBits : bad bmp", NULL);
00821 return NULL;
00822 }
00823
00824 if ( ! Bmp->LockOwner )
00825 {
00826 geErrorLog_AddString(-1,"GetBits : not a lock", NULL);
00827 return NULL;
00828 }
00829
00830 if ( Bmp->DriverHandle )
00831 {
00832 assert(Bmp->Driver);
00833 if ( ! Bmp->Driver->THandle_Lock(Bmp->DriverHandle,Bmp->DriverMipLock,&bits) )
00834 {
00835 geErrorLog_AddString(-1,"GetBits : THandle_Lock", NULL);
00836 return NULL;
00837 }
00838
00839 Bmp->DriverBitsLocked = GE_TRUE;
00840 }
00841 else
00842 {
00843 bits = Bmp->Data[0];
00844 }
00845
00846 return bits;
00847 }
00848
00849
00850
00851 geBitmap * geBitmap_CreateLock_CopyInfo(geBitmap *BmpSrc,int LockCnt,int mip)
00852 {
00853 geBitmap * Bmp;
00854
00855 assert( geBitmap_IsValid(BmpSrc) );
00856
00857
00858
00859 Bmp = geBitmap_Create_Base();
00860 if ( ! Bmp )
00861 return NULL;
00862
00863 geBitmap_MakeMipInfo(&(BmpSrc->Info),mip,&(Bmp->Info));
00864 geBitmap_MakeMipInfo(&(BmpSrc->DriverInfo),mip,&(Bmp->DriverInfo));
00865 Bmp->DriverFlags = BmpSrc->DriverFlags;
00866 Bmp->DriverGamma = BmpSrc->DriverGamma;
00867 Bmp->DriverGammaLast = BmpSrc->DriverGammaLast;
00868
00869 Bmp->Info.Palette = NULL;
00870 Bmp->DriverInfo.Palette = NULL;
00871
00872 Bmp->Driver = BmpSrc->Driver;
00873 Bmp->PreferredFormat= BmpSrc->PreferredFormat;
00874
00875 Bmp->LockOwner = BmpSrc;
00876 geBitmap_CreateRef(BmpSrc);
00877
00878 BmpSrc->LockCount += LockCnt;
00879
00880 return Bmp;
00881 }
00882
00883 void geBitmap_MakeMipInfo(geBitmap_Info *Src,int mip,geBitmap_Info * Target)
00884 {
00885 assert( Src && Target );
00886 assert( mip >= 0 && mip < MAXMIPLEVELS );
00887 *Target = *Src;
00888
00889 Target->Width = SHIFT_R_ROUNDUP(Target->Width,mip);
00890 Target->Height = SHIFT_R_ROUNDUP(Target->Height,mip);
00891 Target->Stride = SHIFT_R_ROUNDUP(Target->Stride,mip);
00892 Target->MinimumMip = Target->MaximumMip = mip;
00893 }
00894
00895 geBitmap * geBitmap_CreateLockFromMip(geBitmap *Src,int mip,
00896 gePixelFormat Format,
00897 geBoolean HasColorKey,
00898 uint32 ColorKey,
00899 int LockCnt)
00900 {
00901 geBitmap * Ret;
00902
00903 assert( geBitmap_IsValid(Src) );
00904 if ( mip < 0 || mip >= MAXMIPLEVELS )
00905 return NULL;
00906
00907
00908
00909 if ( gePixelFormat_BytesPerPel(Format) < 1 )
00910 return NULL;
00911
00912 if ( Src->DriverInfo.Format == Format &&
00913 GE_BOOLSAME(Src->DriverInfo.HasColorKey,HasColorKey) &&
00914 (!HasColorKey || Src->DriverInfo.ColorKey == ColorKey) &&
00915 mip >= Src->DriverInfo.MinimumMip && mip <= Src->DriverInfo.MaximumMip )
00916 {
00917 return geBitmap_CreateLockFromMipOnDriver(Src,mip,LockCnt);
00918 }
00919
00920 if ( Src->DriverHandle )
00921 {
00922 if ( ! geBitmap_Update_DriverToSystem(Src) )
00923 {
00924 return NULL;
00925 }
00926 }
00927
00928 if ( ! Src->Data[mip] )
00929 {
00930 if ( ! geBitmap_MakeSystemMips(Src,mip,mip) )
00931 return NULL;
00932 }
00933
00934 if ( Src->Info.Format == Format &&
00935 GE_BOOLSAME(Src->Info.HasColorKey,HasColorKey) &&
00936 (!HasColorKey || Src->Info.ColorKey == ColorKey) )
00937 {
00938 return geBitmap_CreateLockFromMipSystem(Src,mip,LockCnt);
00939 }
00940
00941 Ret = geBitmap_CreateLock_CopyInfo(Src,LockCnt,mip);
00942
00943 if ( ! Ret )
00944 return NULL;
00945
00946 Ret->Info.Stride = Ret->Info.Width;
00947
00948 Ret->Info.Format = Format;
00949 Ret->Info.ColorKey = ColorKey;
00950 Ret->Info.HasColorKey = HasColorKey;
00951
00952 if ( gePixelFormat_HasPalette(Format) && Src->Info.Palette )
00953 {
00954 Ret->Info.Palette = Src->Info.Palette;
00955 geBitmap_Palette_CreateRef(Ret->Info.Palette);
00956 }
00957
00958 assert( Ret->Alpha == NULL );
00959 if ( ! gePixelFormat_HasGoodAlpha(Format) && Src->Alpha )
00960 {
00961 if ( ! geBitmap_LockForRead(Src->Alpha,&(Ret->Alpha),mip,mip,GE_PIXELFORMAT_8BIT_GRAY,0,0) )
00962 {
00963 geErrorLog_AddString(-1,"CreateLockFromMip : LockForRead failed", NULL);
00964 geBitmap_Destroy(&Ret);
00965 return NULL;
00966 }
00967 assert( Ret->Alpha );
00968 }
00969
00970 assert( geBitmap_IsValid(Ret) );
00971
00972 if ( ! geBitmap_AllocSystemMip(Ret,0) )
00973 {
00974 geBitmap_Destroy(&Ret);
00975 return NULL;
00976 }
00977
00978 if ( ! geBitmap_BlitMip( Src, mip, Ret, 0 ) )
00979 {
00980 geErrorLog_AddString(-1,"CreateLockFromMip : BlitMip failed", NULL);
00981 geBitmap_Destroy(&Ret);
00982 return NULL;
00983 }
00984
00985 return Ret;
00986 }
00987
00988 geBitmap * geBitmap_CreateLockFromMipSystem(geBitmap *Src,int mip,int LockCnt)
00989 {
00990 geBitmap * Ret;
00991
00992 assert( geBitmap_IsValid(Src) );
00993 if ( mip < Src->Info.MinimumMip || mip >= MAXMIPLEVELS )
00994 return NULL;
00995
00996 if ( gePixelFormat_BytesPerPel(Src->Info.Format) < 1 )
00997 return NULL;
00998
00999 if ( ! Src->Data[mip] )
01000 {
01001 if ( ! geBitmap_MakeSystemMips(Src,mip,mip) )
01002 return NULL;
01003 }
01004
01005 Ret = geBitmap_CreateLock_CopyInfo(Src,LockCnt,mip);
01006
01007 if ( ! Ret ) return NULL;
01008
01009 Ret->Data[0] = Src->Data[mip];
01010
01011 Ret->Info.Palette = Src->Info.Palette;
01012 if ( Ret->Info.Palette )
01013 geBitmap_Palette_CreateRef(Ret->Info.Palette);
01014
01015 Ret->DataOwner = Src;
01016 geBitmap_CreateRef(Src);
01017
01018 assert( Ret->Alpha == NULL );
01019 if ( ! gePixelFormat_HasGoodAlpha(Src->Info.Format) && Src->Alpha )
01020 {
01021 if ( ! geBitmap_LockForRead(Src->Alpha,&(Ret->Alpha),mip,mip,GE_PIXELFORMAT_8BIT_GRAY,0,0) )
01022 {
01023 geErrorLog_AddString(-1,"CreateLockFromMipSystem : LockForRead failed", NULL);
01024 geBitmap_Destroy(&Ret);
01025 return NULL;
01026 }
01027 assert( Ret->Alpha );
01028 }
01029
01030 assert( geBitmap_IsValid(Ret) );
01031
01032 return Ret;
01033 }
01034
01035 geBitmap * geBitmap_CreateLockFromMipOnDriver(geBitmap *Src,int mip,int LockCnt)
01036 {
01037 geBitmap * Ret;
01038
01039 assert( geBitmap_IsValid(Src) );
01040 if ( ! Src->DriverHandle || ! Src->Driver || Src->DriverMipLock || mip < Src->DriverInfo.MinimumMip || mip > Src->DriverInfo.MaximumMip )
01041 return NULL;
01042
01043
01044
01045 assert( gePixelFormat_BytesPerPel(Src->DriverInfo.Format) > 0);
01046
01047 Ret = geBitmap_CreateLock_CopyInfo(Src,LockCnt,mip);
01048
01049 if ( ! Ret ) return NULL;
01050
01051 Ret->DriverMipLock = mip;
01052 Ret->DriverHandle = Src->DriverHandle;
01053
01054 Ret->DataOwner = Src;
01055 geBitmap_CreateRef(Src);
01056
01057 Ret->DriverInfo.Palette = Src->DriverInfo.Palette;
01058
01059 if ( ! geBitmap_MakeDriverLockInfo(Ret,mip,&(Ret->DriverInfo)) )
01060 {
01061 geErrorLog_AddString(-1,"CreateLockFromMipOnDriver : UpdateInfo failed", NULL);
01062 geBitmap_Destroy(&Ret);
01063 return NULL;
01064 }
01065
01066 assert(Ret->DriverInfo.Palette == Src->DriverInfo.Palette);
01067
01068 Ret->Info = Ret->DriverInfo;
01069
01070 if ( Ret->DriverInfo.Palette )
01071 geBitmap_Palette_CreateRef(Ret->DriverInfo.Palette);
01072 if ( Ret->Info.Palette )
01073 geBitmap_Palette_CreateRef(Ret->Info.Palette);
01074
01075 assert( geBitmap_IsValid(Ret) );
01076
01077 return Ret;
01078 }
01079
01080
01081
01082 #define MAX_DRIVER_FORMATS (100)
01083
01084 static geBoolean EnumPFCB(geRDriver_PixelFormat *pFormat,void *Context)
01085 {
01086 geRDriver_PixelFormat **pDriverFormatsPtr;
01087 pDriverFormatsPtr = Context;
01088 **pDriverFormatsPtr = *pFormat;
01089 (*pDriverFormatsPtr) += 1;
01090 return GE_TRUE;
01091 }
01092
01093 static int NumBitsOn(uint32 val)
01094 {
01095 uint32 count = 0;
01096 while(val)
01097 {
01098 count += val&1;
01099 val >>= 1;
01100 }
01101 return count;
01102 }
01103
01104 static geBoolean IsInArray(uint32 Val,uint32 *Array,int Len)
01105 {
01106 while(Len--)
01107 {
01108 if ( Val == *Array )
01109 return GE_TRUE;
01110 Array--;
01111 }
01112 return GE_FALSE;
01113 }
01114
01115 geBoolean geBitmap_ChooseDriverFormat(
01116 gePixelFormat SeekFormat1,
01117 gePixelFormat SeekFormat2,
01118 geBoolean SeekCK,
01119 geBoolean SeekAlpha,
01120 geBoolean SeekSeparates,
01121 uint32 SeekFlags,
01122 geRDriver_PixelFormat *DriverFormatsArray,int ArrayLen,
01123 geRDriver_PixelFormat *pTarget)
01124 {
01125 int i,rating;
01126 int FormatRating[MAX_DRIVER_FORMATS];
01127 geRDriver_PixelFormat * DriverPalFormat;
01128 geRDriver_PixelFormat * pf;
01129 geBoolean FoundAlpha;
01130 uint32 SeekMajor,SeekMinor;
01131 const gePixelFormat_Operations *seekops,*pfops;
01132
01133 assert(pTarget && DriverFormatsArray && ArrayLen > 0);
01134
01135 if ( SeekAlpha )
01136 SeekCK = GE_FALSE;
01137
01138 if ( SeekFlags & RDRIVER_PF_ALPHA )
01139 SeekFlags = RDRIVER_PF_ALPHA;
01140 else if ( SeekFlags & RDRIVER_PF_PALETTE )
01141 SeekFlags = RDRIVER_PF_PALETTE;
01142
01143 SeekMajor = SeekFlags & RDRIVER_PF_MAJOR_MASK;
01144 SeekMinor = SeekFlags - SeekMajor;
01145
01146 pf = DriverFormatsArray;
01147 DriverPalFormat = NULL;
01148 for(i=0;i<ArrayLen;i++)
01149 {
01150 if ( pf->Flags & RDRIVER_PF_PALETTE )
01151 {
01152 if ( ! DriverPalFormat || gePixelFormat_HasGoodAlpha(pf->PixelFormat) )
01153 DriverPalFormat = pf;
01154 }
01155 pf++;
01156 }
01157
01158 seekops = gePixelFormat_GetOperations(SeekFormat1);
01159
01160 for(i=0;i<ArrayLen;i++)
01161 {
01162 pf = DriverFormatsArray + i;
01163 rating = 0;
01164
01165
01166
01167
01168
01169
01170
01171
01172
01173
01174
01175
01176
01177
01178
01179
01180
01181
01182
01183
01184
01185
01186
01187
01188 if ( (pf->Flags & RDRIVER_PF_MAJOR_MASK) == SeekMajor )
01189 {
01190 rating += 1<<23;
01191 }
01192 else if ( (pf->Flags & SeekMajor) != SeekMajor )
01193 {
01194 FormatRating[i] = 0;
01195 continue;
01196 }
01197 else
01198 {
01199
01200
01201 rating += (32 - NumBitsOn( (pf->Flags ^ SeekFlags) & RDRIVER_PF_MAJOR_MASK ))<<6;
01202 }
01203
01204 pfops = gePixelFormat_GetOperations(pf->PixelFormat);
01205
01206 if ( pf->PixelFormat == SeekFormat1 )
01207 {
01208 rating += 1<<16;
01209 }
01210 else if ( pf->PixelFormat == SeekFormat2 )
01211 {
01212 rating += 1<<15;
01213 }
01214 else if ( gePixelFormat_IsRaw(SeekFormat1) && gePixelFormat_IsRaw(pf->PixelFormat) )
01215 {
01216 int R,G,B,A;
01217
01218 R = (seekops->RMask >> seekops->RShift) ^ (pfops->RMask >> pfops->RShift);
01219 G = (seekops->GMask >> seekops->GShift) ^ (pfops->GMask >> pfops->GShift);
01220 B = (seekops->BMask >> seekops->BShift) ^ (pfops->BMask >> pfops->BShift);
01221 A = (seekops->AMask >> seekops->AShift) ^ (pfops->AMask >> pfops->AShift);
01222 R = 8 - NumBitsOn(R);
01223 G = 8 - NumBitsOn(G);
01224 B = 8 - NumBitsOn(B);
01225 A = 4*(8 - NumBitsOn(A));
01226 rating += (R + G + B + A);
01227 }
01228 else
01229 {
01230
01231
01232 rating += 16;
01233 }
01234
01235 FoundAlpha = GE_FALSE;
01236
01237 if ( NumBitsOn(pfops->AMask) > 2 )
01238 FoundAlpha = GE_TRUE;
01239
01240 if ( gePixelFormat_HasPalette(pf->PixelFormat) )
01241 {
01242
01243
01244 assert(DriverPalFormat);
01245 if ( gePixelFormat_HasGoodAlpha(DriverPalFormat->PixelFormat) )
01246 FoundAlpha = GE_TRUE;
01247 }
01248
01249 if ( SeekAlpha && FoundAlpha )
01250 rating += 1<<24;
01251 else if ( (!SeekAlpha) && (!FoundAlpha) )
01252 rating += 1<<10;
01253 else if ( SeekAlpha )
01254 {
01255 if ( NumBitsOn(pfops->AMask) || pf->Flags & RDRIVER_PF_CAN_DO_COLORKEY )
01256 {
01257
01258 rating += 1<<19;
01259 }
01260 }
01261
01262 if ( (pf->Flags & RDRIVER_PF_HAS_ALPHA) && SeekSeparates )
01263 {
01264
01265 rating += 1<<25;
01266 }
01267
01268 if ( SeekCK )
01269 {
01270 if ( pf->PixelFormat == GE_PIXELFORMAT_16BIT_1555_ARGB )
01271 {
01272 rating += 1<<23;
01273 }
01274 else if ( FoundAlpha )
01275 {
01276 rating += 1<<18;
01277 }
01278 }
01279
01280 if ( GE_BOOLSAME((pf->Flags & RDRIVER_PF_CAN_DO_COLORKEY),SeekCK) )
01281 {
01282 rating += 1<<17;
01283 }
01284
01285 FormatRating[i] = rating;
01286 }
01287
01288 rating = 0;
01289
01290 for(i=0;i<ArrayLen;i++)
01291 {
01292 if ( FormatRating[i] > rating )
01293 {
01294 rating = FormatRating[i];
01295 *pTarget = DriverFormatsArray[i];
01296 }
01297 }
01298
01299 if ( rating == 0)
01300 {
01301 geErrorLog_AddString(-1,"ChooseDriverFormat : no valid formats found!", NULL);
01302 return GE_FALSE;
01303 }
01304
01305 return GE_TRUE;
01306 }
01307 #if 0
01308 geBoolean geBitmap_ChooseDriverFormat(
01309 gePixelFormat SeekFormat1,
01310 gePixelFormat SeekFormat2,
01311 geBoolean SeekCK,
01312 geBoolean SeekAlpha,
01313 geBoolean SeekSeparates,
01314 uint32 SeekFlags,
01315 geRDriver_PixelFormat *DriverFormatsArray,int ArrayLen,
01316 geRDriver_PixelFormat *pTarget)
01317 {
01318 int i,rating;
01319 int FormatRating[MAX_DRIVER_FORMATS];
01320 geRDriver_PixelFormat * DriverPalFormat;
01321 geRDriver_PixelFormat * pf;
01322 geBoolean FoundAlpha;
01323 uint32 SeekMajor,SeekMinor;
01324 const gePixelFormat_Operations *seekops,*pfops;
01325
01326 assert(pTarget && DriverFormatsArray && ArrayLen > 0);
01327
01328 #if 0 // @@
01329 if ( SeekAlpha )
01330 SeekCK = GE_FALSE;
01331 #endif
01332
01333 if ( SeekFlags & RDRIVER_PF_ALPHA )
01334 SeekFlags = RDRIVER_PF_ALPHA;
01335 else if ( SeekFlags & RDRIVER_PF_PALETTE )
01336 SeekFlags = RDRIVER_PF_PALETTE;
01337
01338 if ( ! SeekFormat1 )
01339 SeekFormat1 = SeekFormat2;
01340
01341 SeekMajor = SeekFlags & RDRIVER_PF_MAJOR_MASK;
01342 SeekMinor = SeekFlags - SeekMajor;
01343
01344 pf = DriverFormatsArray;
01345 DriverPalFormat = NULL;
01346 for(i=0;i<ArrayLen;i++)
01347 {
01348 if ( pf->Flags & RDRIVER_PF_PALETTE )
01349 {
01350 assert( gePixelFormat_IsRaw(pf->PixelFormat) );
01351 if ( ! DriverPalFormat || gePixelFormat_HasGoodAlpha(pf->PixelFormat) )
01352 DriverPalFormat = pf;
01353 }
01354 pf++;
01355 }
01356
01357 seekops = gePixelFormat_GetOperations(SeekFormat1);
01358
01359 for(i=0;i<ArrayLen;i++)
01360 {
01361 pf = DriverFormatsArray + i;
01362 rating = 0;
01363
01364
01365
01366
01367
01368
01369
01370
01371
01372
01373
01374
01375
01376
01377
01378 if ( (pf->Flags & RDRIVER_PF_MAJOR_MASK) == SeekMajor )
01379 {
01380 rating += 1<<23;
01381 }
01382 else if ( (pf->Flags & SeekMajor) != SeekMajor )
01383 {
01384 FormatRating[i] = 0;
01385 continue;
01386 }
01387 else
01388 {
01389
01390
01391 rating += (32 - NumBitsOn( (pf->Flags ^ SeekFlags) & RDRIVER_PF_MAJOR_MASK )) <<6;
01392 }
01393
01394 pfops = gePixelFormat_GetOperations(pf->PixelFormat);
01395
01396 if ( pf->PixelFormat == SeekFormat1 )
01397 {
01398 rating += 1<<22;
01399 }
01400 else if ( pf->PixelFormat == SeekFormat2 )
01401 {
01402 rating += 1<<21;
01403 }
01404 else if ( gePixelFormat_IsRaw(SeekFormat1) && gePixelFormat_IsRaw(pf->PixelFormat) )
01405 {
01406 int R,G,B,A;
01407
01408 R = (seekops->RMask >> seekops->RShift) ^ (pfops->RMask >> pfops->RShift);
01409 G = (seekops->GMask >> seekops->GShift) ^ (pfops->GMask >> pfops->GShift);
01410 B = (seekops->BMask >> seekops->BShift) ^ (pfops->BMask >> pfops->BShift);
01411 A = (seekops->AMask >> seekops->AShift) ^ (pfops->AMask >> pfops->AShift);
01412 R = 8 - NumBitsOn(R);
01413 G = 8 - NumBitsOn(G);
01414 B = 8 - NumBitsOn(B);
01415 A = 4*(8 - NumBitsOn(A));
01416 rating += R + G + B + A;
01417 }
01418
01419 FoundAlpha = GE_FALSE;
01420
01421 if ( NumBitsOn(pfops->AMask) > 2 )
01422 FoundAlpha = GE_TRUE;
01423
01424 if ( gePixelFormat_HasPalette(pf->PixelFormat) )
01425 {
01426
01427
01428 assert(DriverPalFormat);
01429 if ( gePixelFormat_HasGoodAlpha(DriverPalFormat->PixelFormat) )
01430 FoundAlpha = GE_TRUE;
01431 }
01432
01433 if ( SeekAlpha && FoundAlpha )
01434 rating += 1<<24;
01435 else if ( (!SeekAlpha) && (!FoundAlpha) )
01436 rating += 1<<16;
01437
01438 if ( (pf->Flags & RDRIVER_PF_HAS_ALPHA) && SeekSeparates )
01439 {
01440
01441 rating += 1<<25;
01442 }
01443
01444 if ( (pf->PixelFormat == GE_PIXELFORMAT_16BIT_1555_ARGB) && SeekCK )
01445 {
01446 rating += 1<<23;
01447 }
01448 else if ( GE_BOOLSAME((pf->Flags & RDRIVER_PF_CAN_DO_COLORKEY),SeekCK) )
01449 {
01450 rating += 1<<20;
01451 }
01452
01453 if ( SeekCK && FoundAlpha )
01454 {
01455 rating += 1<<17;
01456 }
01457
01458 FormatRating[i] = rating;
01459 }
01460
01461 rating = 0;
01462
01463 for(i=0;i<ArrayLen;i++)
01464 {
01465 if ( FormatRating[i] > rating )
01466 {
01467 rating = FormatRating[i];
01468 *pTarget = DriverFormatsArray[i];
01469 }
01470 }
01471
01472 if ( rating == 0)
01473 {
01474 geErrorLog_AddString(-1,"ChooseDriverFormat : no valid formats found!", NULL);
01475 return GE_FALSE;
01476 }
01477
01478 return GE_TRUE;
01479 }
01480 #endif
01481
01482 geRDriver_THandle * geBitmap_CreateTHandle(DRV_Driver *Driver,int Width,int Height,int NumMipLevels,
01483 gePixelFormat SeekFormat1,gePixelFormat SeekFormat2,geBoolean SeekCK,geBoolean SeekAlpha,geBoolean SeekSeparates,uint32 DriverFlags)
01484 {
01485 geRDriver_PixelFormat DriverFormats[MAX_DRIVER_FORMATS];
01486 geRDriver_PixelFormat *DriverFormatsPtr;
01487 int DriverFormatsCount;
01488 geRDriver_PixelFormat DriverFormat;
01489 geRDriver_THandle * Ret;
01490
01491 DriverFormatsPtr = DriverFormats;
01492 Driver->EnumPixelFormats(EnumPFCB,&DriverFormatsPtr);
01493 DriverFormatsCount = ((uint32)DriverFormatsPtr - (uint32)DriverFormats)/sizeof(*DriverFormatsPtr);
01494 assert(DriverFormatsCount < MAX_DRIVER_FORMATS && DriverFormatsCount >= 0);
01495
01496 if ( DriverFormatsCount == 0 )
01497 {
01498 geErrorLog_AddString(-1,"Bitmap_CreateTHandle : no formats found!", NULL);
01499 return NULL;
01500 }
01501
01502 if ( ! SeekFormat1 )
01503 SeekFormat1 = SeekFormat2;
01504 else if ( ! SeekFormat2 )
01505 SeekFormat2 = SeekFormat1;
01506
01507 assert( gePixelFormat_IsValid(SeekFormat1) );
01508 assert( gePixelFormat_IsValid(SeekFormat2) );
01509
01510
01511 if ( ! geBitmap_ChooseDriverFormat(SeekFormat1,SeekFormat2,SeekCK,SeekAlpha,SeekSeparates,DriverFlags,
01512 DriverFormats,DriverFormatsCount,&DriverFormat) )
01513 return NULL;
01514
01515 assert( gePixelFormat_IsValid(DriverFormat.PixelFormat) );
01516
01517 #if 1 //{
01518 Log_Printf("Bitmap : Chose %s for %s",
01519 gePixelFormat_Description(DriverFormat.PixelFormat),
01520 gePixelFormat_Description(SeekFormat1));
01521
01522 if ( SeekFormat1 != SeekFormat2 )
01523 Log_Printf(" (%s)",gePixelFormat_Description(SeekFormat2));
01524 if ( SeekCK )
01525 Log_Printf(" (sought CK)");
01526 if ( SeekAlpha )
01527 Log_Printf(" (sought Alpha)");
01528 if ( DriverFormat.Flags & RDRIVER_PF_2D )
01529 Log_Printf(" (2D)");
01530 if ( DriverFormat.Flags & RDRIVER_PF_3D )
01531 Log_Printf(" (3D)");
01532 if ( DriverFormat.Flags & RDRIVER_PF_CAN_DO_COLORKEY )
01533 Log_Printf(" (can CK)");
01534 if ( DriverFormat.Flags & RDRIVER_PF_PALETTE )
01535 Log_Printf(" (Palette)");
01536 if ( DriverFormat.Flags & RDRIVER_PF_ALPHA )
01537 Log_Printf(" (Alpha)");
01538 if ( DriverFormat.Flags & RDRIVER_PF_LIGHTMAP )
01539 Log_Printf(" (Lightmap)");
01540
01541 Log_Printf("\n");
01542 #endif //}
01543
01544 Ret = Driver->THandle_Create(
01545 Width,Height,
01546 NumMipLevels,
01547 &DriverFormat);
01548
01549 if ( ! Ret )
01550 {
01551 geErrorLog_AddString(-1, Driver->LastErrorStr, NULL);
01552 geErrorLog_AddString(-1,"Bitmap_CreateTHandle : Driver->THandle_Create failed", NULL);
01553 }
01554
01555 return Ret;
01556 }
01557
01558 GENESISAPI geBoolean GENESISCC geBitmap_HasAlpha(const geBitmap * Bmp)
01559 {
01560 assert( geBitmap_IsValid(Bmp) );
01561
01562 if ( Bmp->Alpha )
01563 return GE_TRUE;
01564
01565 if ( gePixelFormat_HasGoodAlpha(Bmp->Info.Format) )
01566 return GE_TRUE;
01567
01568 if ( gePixelFormat_HasPalette(Bmp->Info.Format) && Bmp->Info.Palette )
01569 {
01570 if ( gePixelFormat_HasGoodAlpha(Bmp->Info.Palette->Format) )
01571 return GE_TRUE;
01572 }
01573
01574 return GE_FALSE;
01575 }
01576
01577 geBoolean BITMAP_GENESIS_INTERNAL geBitmap_AttachToDriver(geBitmap *Bmp,
01578 DRV_Driver * Driver, uint32 DriverFlags)
01579 {
01580
01581
01582
01583
01584
01585
01586
01587
01588
01589
01590
01591
01592
01593
01594
01595
01596
01597
01598
01599
01600
01601
01602
01603
01604
01605
01606
01607
01608
01609
01610
01611
01612
01613
01614
01615 assert( geBitmap_IsValid(Bmp) );
01616
01617 if ( Bmp->LockOwner || Bmp->DataOwner || Bmp->LockCount )
01618 {
01619 geErrorLog_AddString(-1,"AttachToDriver : not an isolated bitmap", NULL);
01620 return GE_FALSE;
01621 }
01622
01623 if ( Bmp->DriverHandle && Bmp->Driver == Driver )
01624 {
01625 assert( DriverFlags == 0 || DriverFlags == Bmp->DriverFlags );
01626 return GE_TRUE;
01627 }
01628
01629 if ( ! geBitmap_DetachDriver(Bmp,GE_TRUE) )
01630 {
01631 geErrorLog_AddString(-1,"AttachToDriver : detach failed", NULL);
01632 return GE_FALSE;
01633 }
01634
01635 if ( DriverFlags == 0 )
01636 {
01637 DriverFlags = Bmp->DriverFlags;
01638 if ( ! DriverFlags )
01639 {
01640
01641
01642 DriverFlags = RDRIVER_PF_3D;
01643 }
01644 }
01645
01646 if ( Driver )
01647 {
01648 int NumMipLevels;
01649 int Width,Height;
01650 geBoolean WantAlpha;
01651 geRDriver_THandle * DriverHandle;
01652
01653
01654
01655
01656 NumMipLevels = max(Bmp->SeekMipCount,(Bmp->Info.MaximumMip + 1));
01657 if ( NumMipLevels > 4 ) NumMipLevels = 4;
01658
01659
01660
01661 Width = Bmp->Info.Width;
01662 Height = Bmp->Info.Height;
01663
01664 WantAlpha = geBitmap_HasAlpha(Bmp);
01665 if ( gePixelFormat_HasGoodAlpha(Bmp->PreferredFormat) )
01666 WantAlpha = GE_TRUE;
01667
01668 assert( geBitmap_IsValid(Bmp) );
01669
01670 DriverHandle = geBitmap_CreateTHandle(Driver,Width,Height,NumMipLevels,
01671 Bmp->PreferredFormat,Bmp->Info.Format,Bmp->Info.HasColorKey,
01672 WantAlpha, (Bmp->Alpha) ? GE_TRUE : GE_FALSE,
01673 DriverFlags);
01674
01675 assert( geBitmap_IsValid(Bmp) );
01676
01677 if ( ! DriverHandle )
01678 return GE_FALSE;
01679
01680 Bmp->DriverHandle = DriverHandle;
01681 Bmp->Driver = Driver;
01682 Bmp->DriverFlags = DriverFlags;
01683
01684 #ifdef _DEBUG
01685 Bmp->DriverInfo = Bmp->Info;
01686 assert( geBitmap_IsValid(Bmp) );
01687 #endif
01688 clear(&(Bmp->DriverInfo));
01689
01690 if ( ! geBitmap_MakeDriverLockInfo(Bmp,0,&(Bmp->DriverInfo)) )
01691 {
01692 geErrorLog_AddString(-1,"AttachToDriver : updateinfo", NULL);
01693 return GE_FALSE;
01694 }
01695
01696 Bmp->DriverInfo.MinimumMip = 0;
01697 Bmp->DriverInfo.MaximumMip = NumMipLevels - 1;
01698
01699 assert( geBitmap_IsValid(Bmp) );
01700
01701 assert( geBitmap_IsValid(Bmp) );
01702
01703 if ( ! geBitmap_Update_SystemToDriver(Bmp) )
01704 {
01705 geErrorLog_AddString(-1,"AttachToDriver : Update_SystemToDriver", NULL);
01706 Driver->THandle_Destroy(Bmp->DriverHandle);
01707 Bmp->DriverHandle = NULL;
01708 return GE_FALSE;
01709 }
01710
01711
01712
01713 }
01714
01715 return GE_TRUE;
01716 }
01717
01718 geBoolean geBitmap_FixDriverFlags(uint32 *pFlags)
01719 {
01720 uint32 DriverFlags;
01721 assert(pFlags);
01722 DriverFlags = *pFlags;
01723
01724 if ( DriverFlags & RDRIVER_PF_COMBINE_LIGHTMAP )
01725 DriverFlags |= RDRIVER_PF_3D;
01726 if ( DriverFlags & RDRIVER_PF_CAN_DO_COLORKEY )
01727 {
01728
01729
01730 DriverFlags ^= RDRIVER_PF_CAN_DO_COLORKEY;
01731
01732 }
01733 if ( (DriverFlags & RDRIVER_PF_COMBINE_LIGHTMAP) &&
01734 (DriverFlags & (RDRIVER_PF_LIGHTMAP | RDRIVER_PF_PALETTE) ) )
01735 return GE_FALSE;
01736 if ( NumBitsOn(DriverFlags & RDRIVER_PF_MAJOR_MASK) == 0 )
01737 return GE_FALSE;
01738 *pFlags = DriverFlags;
01739 return GE_TRUE;
01740 }
01741
01742 geBoolean BITMAP_GENESIS_INTERNAL geBitmap_SetDriverFlags(geBitmap *Bmp,uint32 Flags)
01743 {
01744 assert( geBitmap_IsValid(Bmp) );
01745 assert(Flags);
01746 if ( ! geBitmap_FixDriverFlags(&Flags) )
01747 {
01748 Bmp->DriverFlags = 0;
01749 return GE_FALSE;
01750 }
01751 Bmp->DriverFlags = Flags;
01752 return GE_TRUE;
01753 }
01754
01755 geBoolean BITMAP_GENESIS_INTERNAL geBitmap_DetachDriver(geBitmap *Bmp,geBoolean DoUpdate)
01756 {
01757 geBoolean Ret = GE_TRUE;
01758
01759 assert(geBitmap_IsValid(Bmp) );
01760
01761 if ( Bmp->LockOwner || Bmp->DataOwner || Bmp->LockCount )
01762 {
01763 geErrorLog_AddString(-1,"DetachDriver : not an isolated bitmap!", NULL);
01764 return GE_FALSE;
01765 }
01766
01767 if ( Bmp->RefCount > 1 )
01768 DoUpdate = GE_TRUE;
01769
01770 if ( Bmp->Driver && Bmp->DriverHandle )
01771 {
01772 if ( DoUpdate )
01773 {
01774 if ( ! geBitmap_Update_DriverToSystem(Bmp) )
01775 {
01776 geErrorLog_AddString(-1,"DetachDriver : Update_DriverToSystem", NULL);
01777 Ret = GE_FALSE;
01778 }
01779 assert(Bmp->DriverDataChanged == GE_FALSE);
01780 }
01781 Bmp->Driver->THandle_Destroy(Bmp->DriverHandle);
01782 Bmp->DriverHandle = NULL;
01783 }
01784
01785 if ( Bmp->DriverInfo.Palette )
01786 {
01787
01788 if ( ! Bmp->Info.Palette )
01789 {
01790 geBitmap_Palette * NewPal;
01791 gePixelFormat Format;
01792 Format = Bmp->DriverInfo.Palette->Format;
01793 NewPal = geBitmap_Palette_Create(Format,256);
01794 if ( NewPal )
01795 {
01796 if ( geBitmap_Palette_Copy(Bmp->DriverInfo.Palette,NewPal) )
01797 {
01798 Bmp->Info.Palette = NewPal;
01799 }
01800 else
01801 {
01802 geBitmap_Palette_Destroy(&NewPal);
01803 }
01804 }
01805 }
01806
01807 geBitmap_Palette_Destroy(&(Bmp->DriverInfo.Palette));
01808 }
01809
01810 if ( Bmp->Alpha )
01811 {
01812 if ( ! geBitmap_DetachDriver(Bmp->Alpha,DoUpdate) )
01813 {
01814 geErrorLog_AddString(-1,"DetachDriver : detach alpha", NULL);
01815 Ret = GE_FALSE;
01816 }
01817 }
01818
01819 Bmp->DriverInfo.Width = Bmp->DriverInfo.Height = Bmp->DriverInfo.Stride = 0;
01820 Bmp->DriverInfo.MinimumMip = Bmp->DriverInfo.MaximumMip = 0;
01821 Bmp->DriverInfo.ColorKey = Bmp->DriverInfo.HasColorKey = Bmp->DriverInfo.Format = 0;
01822 Bmp->DriverInfo.Palette = NULL;
01823 Bmp->DriverMipLock = 0;
01824 Bmp->DriverBitsLocked = GE_FALSE;
01825 Bmp->DriverDataChanged = GE_FALSE;
01826 Bmp->DriverHandle = NULL;
01827 Bmp->Driver = NULL;
01828
01829
01830
01831 return Ret;
01832 }
01833
01834 geBoolean GENESISCC geBitmap_SetGammaCorrection_DontChange(geBitmap *Bmp,geFloat Gamma)
01835 {
01836 assert(geBitmap_IsValid(Bmp));
01837 assert( Gamma > 0.0f );
01838
01839 if ( ! Bmp->DriverGammaSet )
01840 {
01841 Bmp->DriverGammaLast = Bmp->DriverGamma;
01842 Bmp->DriverGamma = Gamma;
01843 }
01844
01845 return GE_TRUE;
01846 }
01847
01848 GENESISAPI geBoolean GENESISCC geBitmap_SetGammaCorrection(geBitmap *Bmp,geFloat Gamma,geBoolean Apply)
01849 {
01850 assert(geBitmap_IsValid(Bmp));
01851 assert( Gamma > 0.0f );
01852
01853
01854
01855
01856
01857
01858
01859
01860
01861
01862
01863
01864
01865 if ( Apply && Bmp->DriverHandle )
01866 {
01867 if ( fabs(Bmp->DriverGamma - Gamma) > 0.1f )
01868 {
01869 if ( gePixelFormat_BytesPerPel(Bmp->Info.Format) == 0 && Bmp->DriverHandle )
01870 {
01871
01872
01873 if ( (Bmp->DriverGammaLast >= Bmp->DriverGamma && Bmp->DriverGamma >= Gamma) ||
01874 (Bmp->DriverGammaLast <= Bmp->DriverGamma && Bmp->DriverGamma <= Gamma) )
01875 {
01876
01877
01878
01879 if ( ! geBitmap_Gamma_Apply(Bmp,GE_TRUE) )
01880 return GE_FALSE;
01881
01882 Bmp->DriverGammaLast = Bmp->DriverGamma;
01883 Bmp->DriverGamma = Gamma;
01884
01885
01886 if ( ! geBitmap_Gamma_Apply(Bmp,GE_FALSE) )
01887 return GE_FALSE;
01888 }
01889 else
01890 {
01891
01892
01893 if ( ! geBitmap_Update_DriverToSystem(Bmp) )
01894 return GE_FALSE;
01895
01896 Bmp->DriverGammaLast = Bmp->DriverGamma = Gamma;
01897
01898 if ( ! geBitmap_Update_SystemToDriver(Bmp) )
01899 return GE_FALSE;
01900 }
01901 }
01902 else
01903 {
01904 if ( ! geBitmap_Update_DriverToSystem(Bmp) )
01905 return GE_FALSE;
01906
01907 Bmp->DriverGammaLast = Bmp->DriverGamma = Gamma;
01908
01909 if ( ! geBitmap_Update_SystemToDriver(Bmp) )
01910 return GE_FALSE;
01911 }
01912 }
01913 }
01914 else
01915 {
01916 Bmp->DriverGamma = Gamma;
01917 }
01918 Bmp->DriverGammaSet = GE_TRUE;
01919
01920 return GE_TRUE;
01921 }
01922
01923 geRDriver_THandle * BITMAP_GENESIS_INTERNAL geBitmap_GetTHandle(const geBitmap *Bmp)
01924 {
01925
01926
01927 return Bmp->DriverHandle;
01928 }
01929
01930 geBoolean geBitmap_Update_SystemToDriver(geBitmap *Bmp)
01931 {
01932 geBitmap * SrcLocks[MAXMIPLEVELS];
01933 geBoolean Ret,MipsChanged;
01934 int mip,mipMin,mipMax;
01935 geRDriver_THandle * SaveDriverHandle;
01936 geBitmap * SaveAlpha;
01937 int SaveMaxMip;
01938
01939 assert( geBitmap_IsValid(Bmp) );
01940
01948 if ( Bmp->LockOwner )
01949 Bmp = Bmp->LockOwner;
01950
01951 if ( Bmp->LockCount > 0 || Bmp->DataOwner )
01952 {
01953 geErrorLog_AddString(-1,"Update_SystemToDriver : not an original bitmap", NULL);
01954 return GE_FALSE;
01955 }
01956
01957 if ( ! Bmp->DriverHandle )
01958 {
01959 geErrorLog_AddString(-1,"Update_SystemToDriver : no driver data", NULL);
01960 return GE_FALSE;
01961 }
01962
01963 MipsChanged = GE_FALSE;
01964 for(mip=Bmp->DriverInfo.MinimumMip;mip<=Bmp->DriverInfo.MaximumMip;mip++)
01965 {
01966 if ( Bmp->Modified[mip] && mip != Bmp->Info.MinimumMip )
01967 {
01968 assert(Bmp->Data[mip]);
01969 MipsChanged = GE_TRUE;
01970 }
01971 }
01972
01973
01974
01975 #if 0
01976 MipsChanged = GE_TRUE;
01977 #endif
01978
01979 mipMin = Bmp->DriverInfo.MinimumMip;
01980
01981 if ( MipsChanged )
01982 mipMax = Bmp->DriverInfo.MaximumMip;
01983 else
01984 mipMax = mipMin;
01985
01986
01987 SaveDriverHandle = Bmp->DriverHandle;
01988 Bmp->DriverHandle = NULL;
01989
01990 SaveAlpha = Bmp->Alpha;
01991
01992 if ( Bmp->Alpha && ! gePixelFormat_HasGoodAlpha(Bmp->DriverInfo.Format) &&
01993 (Bmp->DriverFlags & RDRIVER_PF_HAS_ALPHA) )
01994 {
01995
01996
01997 Bmp->Alpha = NULL;
01998 }
01999
02000 if ( ! geBitmap_LockForReadNative(Bmp,SrcLocks,mipMin,mipMax) )
02001 {
02002 geErrorLog_AddString(-1,"Update_SystemToDriver : LockForReadNative", NULL);
02003 return GE_FALSE;
02004 }
02005
02006 Ret = GE_TRUE;
02007 Bmp->DriverHandle = SaveDriverHandle;
02008 Bmp->Alpha = NULL;
02009
02010
02011 assert( ! Bmp->DriverDataChanged );
02012
02021 for(mip=mipMin;mip <=mipMax;mip++)
02022 {
02023 geBitmap *SrcMip;
02024 void * SrcBits,*DstBits;
02025 geBitmap_Info DstInfo;
02026
02027 SrcMip = SrcLocks[mip - mipMin];
02028 SrcBits = geBitmap_GetBits(SrcMip);
02029
02030 DstInfo = Bmp->DriverInfo;
02031
02032 if ( ! geBitmap_MakeDriverLockInfo(Bmp,mip,&DstInfo) )
02033 {
02034 geErrorLog_AddString(-1,"Update_SystemToDriver : MakeInfo", NULL);
02035 Ret = GE_FALSE;
02036 continue;
02037 }
02038
02039
02040
02041
02042
02043
02044
02045 if ( ! Bmp->Driver->THandle_Lock(SaveDriverHandle,mip,&DstBits) )
02046 {
02047 geErrorLog_AddString(-1,"Update_SystemToDriver : THandle_Lock", NULL);
02048 Ret = GE_FALSE;
02049 continue;
02050 }
02051
02052 if ( ! SrcBits || ! DstBits )
02053 {
02054 geErrorLog_AddString(-1,"Update_SystemToDriver : No Bits", NULL);
02055 Ret = GE_FALSE;
02056 continue;
02057 }
02058
02059 assert( DstInfo.Palette == Bmp->DriverInfo.Palette );
02060
02061 if ( ! geBitmap_BlitData( &(SrcMip->Info),SrcBits,SrcMip,
02062 &DstInfo, DstBits,Bmp,
02063 SrcMip->Info.Width,SrcMip->Info.Height) )
02064 {
02065 geErrorLog_AddString(-1,"Update_SystemToDriver : BlitData", NULL);
02066
02067 Ret = GE_FALSE;
02068 continue;
02069 }
02070
02071 if ( ! Bmp->Driver->THandle_UnLock(SaveDriverHandle,mip) )
02072 {
02073 geErrorLog_AddString(-1,"Update_SystemToDriver : THandle_UnLock", NULL);
02074 Ret = GE_FALSE;
02075 continue;
02076 }
02077
02078
02079
02080 if ( DstInfo.Palette != Bmp->DriverInfo.Palette )
02081 {
02082
02083 geBitmap_SetPalette(Bmp,DstInfo.Palette);
02084 geBitmap_Palette_Destroy(&(DstInfo.Palette));
02085
02086 }
02087 }
02088
02089 Bmp->Alpha = SaveAlpha;
02090 Bmp->DriverBitsLocked = GE_FALSE;
02091 Bmp->DriverMipLock = 0;
02092 Bmp->DriverDataChanged = GE_FALSE;
02093
02094 geBitmap_UnLockArray(SrcLocks, mipMax - mipMin + 1 );
02095
02096 if ( ! Ret )
02097 {
02098 geErrorLog_AddString(-1,"Update_SystemToDriver : Locking and Blitting error", NULL);
02099 }
02100
02101 if ( Bmp->Alpha && ! gePixelFormat_HasGoodAlpha(Bmp->DriverInfo.Format) &&
02102 (Bmp->DriverFlags & RDRIVER_PF_HAS_ALPHA) )
02103 {
02104 geRDriver_THandle * AlphaTH;
02105
02106
02107
02108 AlphaTH = Bmp->Driver->THandle_GetAlpha(Bmp->DriverHandle);
02109 if ( !AlphaTH || AlphaTH != Bmp->Alpha->DriverHandle)
02110 {
02111 if ( ! geBitmap_AttachToDriver(Bmp->Alpha,Bmp->Driver,Bmp->Alpha->DriverFlags | RDRIVER_PF_ALPHA) )
02112 {
02113 geErrorLog_AddString(-1,"AttachToDriver : attach Alpha", NULL);
02114 return GE_FALSE;
02115 }
02116
02117 assert(Bmp->Alpha->DriverHandle);
02118 if ( ! Bmp->Driver->THandle_SetAlpha(Bmp->DriverHandle,Bmp->Alpha->DriverHandle) )
02119 {
02120 geErrorLog_AddString(-1,"AttachToDriver : THandle_SetAlpha", NULL);
02121 geBitmap_DetachDriver(Bmp->Alpha,GE_FALSE);
02122 geBitmap_DetachDriver(Bmp,GE_FALSE);
02123 return GE_FALSE;
02124 }
02125
02126 AlphaTH = Bmp->Driver->THandle_GetAlpha(Bmp->DriverHandle);
02127 assert(AlphaTH == Bmp->Alpha->DriverHandle);
02128 }
02129 }
02130
02131
02132
02133
02134
02135
02136 SaveMaxMip = Bmp->DriverInfo.MaximumMip;
02137 Bmp->DriverInfo.MaximumMip = mipMax;
02138 if ( ! geBitmap_Gamma_Apply(Bmp,GE_FALSE) )
02139 {
02140 geErrorLog_AddString(-1,"AttachToDriver : Gamma_Apply failed!", NULL);
02141 Ret = GE_FALSE;
02142 }
02143 Bmp->DriverInfo.MaximumMip = SaveMaxMip;
02144
02145 if ( ! MipsChanged && mipMax < Bmp->DriverInfo.MaximumMip )
02146 {
02147 for(mip=mipMax+1;mip<= Bmp->DriverInfo.MaximumMip; mip++)
02148 {
02149 if ( ! geBitmap_UpdateMips(Bmp,mip-1,mip) )
02150 {
02151 geErrorLog_AddString(-1,"AttachToDriver : UpdateMips on driver failed!", NULL);
02152 return GE_FALSE;
02153 }
02154 }
02155 }
02156
02157 Bmp->DriverDataChanged = GE_FALSE;
02158
02159 return Ret;
02160 }
02161
02162 geBoolean geBitmap_Update_DriverToSystem(geBitmap *Bmp)
02163 {
02164 geBitmap *DriverLocks[MAXMIPLEVELS];
02165 geBoolean Ret;
02166 int mip;
02167
02168 assert( geBitmap_IsValid(Bmp) );
02169
02170 if ( Bmp->LockOwner )
02171 Bmp = Bmp->LockOwner;
02172
02173 if ( Bmp->LockCount > 0 || Bmp->DataOwner )
02174 {
02175 geErrorLog_AddString(-1,"Update_DriverToSystem : not an original bitmap", NULL);
02176 return GE_FALSE;
02177 }
02178
02179 if ( ! Bmp->DriverHandle )
02180 {
02181 geErrorLog_AddString(-1,"Update_DriverToSystem : no driver data", NULL);
02182 return GE_FALSE;
02183 }
02184
02185 if ( ! Bmp->DriverDataChanged )
02186 return GE_TRUE;
02187
02188
02189
02190 Log_Puts("Bitmap : Doing Update_DriverToSystem");
02191
02192 if ( ! geBitmap_Gamma_Apply(Bmp,GE_TRUE) )
02193 return GE_FALSE;
02194
02195 if ( Bmp->Info.Palette && Bmp->DriverInfo.Palette )
02196 {
02197 if ( ! geBitmap_Palette_Copy(Bmp->DriverInfo.Palette,Bmp->Info.Palette) )
02198 {
02199 geErrorLog_AddString(-1,"Update_DriverToSystem : Palette_Copy", NULL);
02200 }
02201 }
02202
02203 if ( geBitmap_LockForReadNative(Bmp,DriverLocks,
02204 Bmp->DriverInfo.MinimumMip,Bmp->DriverInfo.MaximumMip) )
02205 {
02206 Ret = GE_TRUE;
02207
02208 for(mip=Bmp->DriverInfo.MinimumMip;mip <=Bmp->DriverInfo.MaximumMip;mip++)
02209 {
02210 geBitmap *MipBmp;
02211 geBitmap_Info SystemInfo;
02212
02213 MipBmp = DriverLocks[mip];
02214
02215 if ( Bmp->Modified[mip] )
02216 {
02217 void *DriverBits,*SystemBits;
02218 DriverBits = geBitmap_GetBits(MipBmp);
02219 assert( MipBmp->DriverBitsLocked );
02220
02221 if ( ! geBitmap_AllocSystemMip(Bmp,mip) )
02222 Ret = GE_FALSE;
02223
02224 SystemBits = Bmp->Data[mip];
02225
02226 geBitmap_MakeMipInfo(&(Bmp->Info),mip,&SystemInfo);
02227
02228 if ( DriverBits && SystemBits )
02229 {
02230
02231
02232 if ( ! geBitmap_BlitData( &(MipBmp->Info), DriverBits, MipBmp,
02233 &SystemInfo, SystemBits, Bmp,
02234 SystemInfo.Width,SystemInfo.Height) )
02235 Ret = GE_FALSE;
02236 }
02237 else
02238 {
02239 Ret = GE_FALSE;
02240 }
02241 }
02242
02243 geBitmap_UnLock(DriverLocks[mip]);
02244 }
02245
02246 Bmp->DriverDataChanged = GE_FALSE;
02247 }
02248 else
02249 {
02250 Ret = GE_FALSE;
02251 }
02252
02253 if ( ! Ret )
02254 {
02255 geErrorLog_AddString(-1,"Update_DriverToSystem : Locking and Blitting error", NULL);
02256 }
02257
02258 if ( ! geBitmap_Gamma_Apply(Bmp,GE_FALSE) )
02259 return GE_FALSE;
02260
02261 return Ret;
02262 }
02263
02264
02265
02266
02267
02268 GENESISAPI geBoolean GENESISCC geBitmap_RefreshMips(geBitmap *Bmp)
02269 {
02270 int mip;
02271
02272 assert( geBitmap_IsValid(Bmp) );
02273
02274 if ( Bmp->LockOwner || Bmp->LockCount || Bmp->DataOwner )
02275 return GE_FALSE;
02276
02277 for(mip = (Bmp->Info.MinimumMip + 1);mip <= Bmp->Info.MaximumMip;mip++)
02278 {
02279 if ( Bmp->Data[mip] && !(Bmp->Modified[mip]) )
02280 {
02281 int src;
02282 src = mip-1;
02283 while( ! Bmp->Data[src] )
02284 {
02285 src--;
02286 if ( src < Bmp->Info.MinimumMip )
02287 return GE_FALSE;
02288 }
02289 if ( ! geBitmap_UpdateMips(Bmp,src,mip) )
02290 return GE_FALSE;
02291 }
02292 }
02293
02294 #if 0 // never turn off a modified flag
02295 for(mip=0;mip<MAXMIPLEVELS;mip++)
02296 Bmp->Modified[mip] = GE_FALSE;
02297 #endif
02298
02299 return GE_TRUE;
02300 }
02301
02302 GENESISAPI geBoolean GENESISCC geBitmap_UpdateMips(geBitmap *Bmp,int fm,int to)
02303 {
02304 geBitmap * Locks[MAXMIPLEVELS];
02305 void *FmBits,*ToBits;
02306 geBitmap_Info FmInfo,ToInfo;
02307 geBoolean Ret = GE_FALSE;
02308
02309 assert( geBitmap_IsValid(Bmp) );
02310
02311 if ( Bmp->LockOwner || Bmp->LockCount > 0 || Bmp->DataOwner )
02312 return GE_FALSE;
02313
02314 if ( fm >= to )
02315 return GE_FALSE;
02316
02317 if ( Bmp->DriverHandle )
02318 {
02319
02320
02321 if ( ! geBitmap_LockForWrite(Bmp,Locks,fm,to) )
02322 return GE_FALSE;
02323
02324 if ( geBitmap_GetInfo(Locks[0],&FmInfo,NULL) && geBitmap_GetInfo(Locks[to - fm],&ToInfo,NULL) )
02325 {
02326 FmBits = geBitmap_GetBits(Locks[0]);
02327 ToBits = geBitmap_GetBits(Locks[to - fm]);
02328
02329 if ( FmBits && ToBits )
02330 {
02331 Ret = geBitmap_UpdateMips_Data( &FmInfo, FmBits,
02332 &ToInfo, ToBits );
02333 }
02334 }
02335
02336 geBitmap_UnLockArray_NoChange(Locks,to - fm + 1);
02337 }
02338 else
02339 {
02340 Ret = geBitmap_UpdateMips_System(Bmp,fm,to);
02341 }
02342
02343 return Ret;
02344 }
02345
02346 geBoolean geBitmap_UpdateMips_System(geBitmap *Bmp,int fm,int to)
02347 {
02348 geBitmap_Info FmInfo,ToInfo;
02349 geBoolean Ret;
02350
02351 assert( geBitmap_IsValid(Bmp) );
02352
02353
02354
02355 if ( Bmp->LockOwner )
02356 Bmp = Bmp->LockOwner;
02357
02358
02359 if ( Bmp->DataOwner )
02360 return GE_FALSE;
02361
02362
02363 if ( gePixelFormat_BytesPerPel(Bmp->Info.Format) < 1 )
02364 return GE_TRUE;
02365
02366 while(Bmp->Data[fm] == NULL || fm == to )
02367 {
02368 fm--;
02369 if ( fm < 0 )
02370 return GE_FALSE;
02371 }
02372
02373 if ( fm < Bmp->Info.MinimumMip || fm > Bmp->Info.MaximumMip ||
02374 to < fm || to >= MAXMIPLEVELS )
02375 return GE_FALSE;
02376
02377 if ( ! Bmp->Data[to] )
02378 {
02379 if ( ! geBitmap_AllocSystemMip(Bmp,to) )
02380 return GE_FALSE;
02381 }
02382
02383 assert( to > fm && fm >= 0 );
02384
02385 FmInfo = ToInfo = Bmp->Info;
02386
02387 FmInfo.Width = SHIFT_R_ROUNDUP(Bmp->Info.Width ,fm);
02388 FmInfo.Height= SHIFT_R_ROUNDUP(Bmp->Info.Height,fm);
02389 FmInfo.Stride= SHIFT_R_ROUNDUP(Bmp->Info.Stride,fm);
02390 ToInfo.Width = SHIFT_R_ROUNDUP(Bmp->Info.Width ,to);
02391 ToInfo.Height= SHIFT_R_ROUNDUP(Bmp->Info.Height,to);
02392 ToInfo.Stride= SHIFT_R_ROUNDUP(Bmp->Info.Stride,to);
02393
02394 Ret = geBitmap_UpdateMips_Data( &FmInfo, Bmp->Data[fm],
02395 &ToInfo, Bmp->Data[to]);
02396
02397 Bmp->Info.MaximumMip = max(Bmp->Info.MaximumMip,to);
02398
02399 return Ret;
02400 }
02401
02402 geBoolean geBitmap_UpdateMips_Data( geBitmap_Info * FmInfo,void * FmBits,
02403 geBitmap_Info * ToInfo,void * ToBits)
02404 {
02405 int fmxtra,tow,toh,toxtra,fmw,fmh,fmstep,x,y,bpp;
02406
02407 assert( FmInfo && ToInfo && FmBits && ToBits );
02408 assert( FmInfo->Format == ToInfo->Format && FmInfo->HasColorKey == ToInfo->HasColorKey );
02409
02410 tow = ToInfo->Width;
02411 toh = ToInfo->Height;
02412 toxtra = ToInfo->Stride - ToInfo->Width;
02413
02414 x = ToInfo->Width;
02415 fmstep = 1;
02416 while( x < FmInfo->Width )
02417 {
02418 fmstep += fmstep;
02419 x += x;
02420 }
02421
02422 fmw = FmInfo->Width;
02423 fmh = FmInfo->Height;
02424 fmxtra = (FmInfo->Stride - tow) * fmstep;
02425
02426
02427
02428
02429
02430 if ( (toh-1)*fmstep > (fmh - 1) )
02431 {
02432 geErrorLog_AddString(-1,"UpdateMips_Data : Vertical mip scaling doesn't match horizontal!", NULL);
02433 return GE_FALSE;
02434 }
02435
02436
02437
02438 bpp = gePixelFormat_BytesPerPel(FmInfo->Format);
02439
02440 if ( fmstep == 2 && bpp > 1 )
02441 {
02442 int R1,G1,B1,A1,R2,G2,B2,A2,R3,G3,B3,A3,R4,G4,B4,A4;
02443 gePixelFormat_ColorGetter GetColor;
02444 gePixelFormat_ColorPutter PutColor;
02445 const gePixelFormat_Operations *ops;
02446 uint8 *fmp,*fmp2,*top;
02447
02448 fmp = FmBits;
02449 top = ToBits;
02450
02451 ops = gePixelFormat_GetOperations(FmInfo->Format);
02452 GetColor = ops->GetColor;
02453 PutColor = ops->PutColor;
02454
02455 fmxtra *= bpp;
02456 toxtra *= bpp;
02457
02458 if ( FmInfo->HasColorKey )
02459 {
02460 uint32 ck,p1,p2,p3,p4;
02461 gePixelFormat_PixelGetter GetPixel;
02462 gePixelFormat_PixelPutter PutPixel;
02463 gePixelFormat_Decomposer DecomposePixel;
02464 int32 PixelComposeRTable[]={0x696C6345,0x21657370};
02465
02466 assert( FmInfo->ColorKey == ToInfo->ColorKey );
02467 ck = FmInfo->ColorKey;
02468 GetPixel = ops->GetPixel;
02469 PutPixel = ops->PutPixel;
02470 DecomposePixel = ops->DecomposePixel;
02471
02472
02473
02474
02475 for(y=toh;y--;)
02476 {
02477
02478 if ( (y+y + 1) == fmh ) fmp2 = fmp;
02479 else fmp2 = fmp + (FmInfo->Stride*bpp);
02480 for(x=tow;x--;)
02481 {
02482 p1 = GetPixel(&fmp);
02483 p2 = GetPixel(&fmp);
02484 p3 = GetPixel(&fmp2);
02485 p4 = GetPixel(&fmp2);
02486 if ( p1 == ck || p4 == ck )
02487 {
02488 PutPixel(&top,ck);
02489 }
02490 else
02491 {
02492
02493 if ( p2 == ck ) p2 = p1;
02494 if ( p3 == ck ) p3 = p4;
02495 DecomposePixel(p1,&R1,&G1,&B1,&A1);
02496 DecomposePixel(p2,&R2,&G2,&B2,&A2);
02497 DecomposePixel(p3,&R3,&G3,&B3,&A3);
02498 DecomposePixel(p4,&R4,&G4,&B4,&A4);
02499 PutColor(&top,(R1+R2+R3+R4+2)>>2,(G1+G2+G3+G4+2)>>2,(B1+B2+B3+B4+2)>>2,(A1+A2+A3+A4+2)>>2);
02500 }
02501 }
02502 fmp += fmxtra;
02503 top += toxtra;
02504 }
02505 }
02506 else
02507 {
02508 for(y=toh;y--;)
02509 {
02510
02511 if ( (y+y + 1) == fmh ) fmp2 = fmp;
02512 else fmp2 = fmp + (FmInfo->Stride*bpp);
02513 for(x=tow;x--;)
02514 {
02515 GetColor(&fmp ,&R1,&G1,&B1,&A1);
02516 GetColor(&fmp ,&R2,&G2,&B2,&A2);
02517 GetColor(&fmp2,&R3,&G3,&B3,&A3);
02518 GetColor(&fmp2,&R4,&G4,&B4,&A4);
02519 PutColor(&top,(R1+R2+R3+R4+2)>>2,(G1+G2+G3+G4+2)>>2,(B1+B2+B3+B4+2)>>2,(A1+A2+A3+A4+2)>>2);
02520 }
02521 fmp += fmxtra;
02522 top += toxtra;
02523 }
02524 }
02525
02526 assert( top == (((uint8 *)ToBits) + ToInfo->Stride * ToInfo->Height * bpp ) );
02527 assert( fmp == (((uint8 *)FmBits) + FmInfo->Stride * ToInfo->Height * 2 * bpp ) );
02528 }
02529 else if ( fmstep == 2 && gePixelFormat_HasPalette(FmInfo->Format) )
02530 {
02531 int R,G,B;
02532 uint8 *fmp,*fmp2,*top;
02533 uint8 paldata[768],*palptr;
02534 int p;
02535 palInfo * PalInfo;
02536
02537 assert(bpp == 1);
02538 assert(FmInfo->Palette);
02539
02540 if ( ! geBitmap_Palette_GetData(FmInfo->Palette,paldata,GE_PIXELFORMAT_24BIT_RGB,256) )
02541 return GE_FALSE;
02542
02543 if ( ! (PalInfo = closestPalInit(paldata)) )
02544 return GE_FALSE;
02545
02546 fmp = FmBits;
02547 top = ToBits;
02548
02549
02550
02551 for(y=toh;y--;)
02552 {
02553
02554 if ( (y*2 + 1) == fmh ) fmp2 = fmp;
02555 else fmp2 = fmp + (FmInfo->Stride*bpp);
02556
02557 for(x=tow;x--;)
02558 {
02559 p = *fmp++;
02560 palptr = paldata + p*3;
02561 R = palptr[0]; G = palptr[1]; B = palptr[2];
02562 p = *fmp++;
02563 palptr = paldata + p*3;
02564 R += palptr[0]; G += palptr[1]; B += palptr[2];
02565 p = *fmp2++;
02566 palptr = paldata + p*3;
02567 R += palptr[0]; G += palptr[1]; B += palptr[2];
02568 p = *fmp2++;
02569 palptr = paldata + p*3;
02570 R += palptr[0]; G += palptr[1]; B += palptr[2];
02571
02572 R = (R+2)>>2;
02573 G = (G+2)>>2;
02574 B = (B+2)>>2;
02575
02576 p = closestPal(R,G,B,PalInfo);
02577 *top++ = p;
02578 }
02579 fmp += fmxtra;
02580 top += toxtra;
02581 }
02582
02583 closestPalFree(PalInfo);
02584
02585 assert( top == (((uint8 *)ToBits) + ToInfo->Stride * ToInfo->Height * bpp ) );
02586 assert( fmp == (((uint8 *)FmBits) + FmInfo->Stride * ToInfo->Height * 2 * bpp ) );
02587 }
02588 else
02589 {
02590
02591
02592
02593
02594
02595
02596 switch( bpp )
02597 {
02598 default:
02599 {
02600 return GE_FALSE;
02601 }
02602 case 1:
02603 {
02604 uint8 *fmp,*top;
02605 fmp = FmBits;
02606 top = ToBits;
02607 for(y=toh;y--;)
02608 {
02609 for(x=tow;x--;)
02610 {
02611 *top++ = *fmp;
02612 fmp += fmstep;
02613 }
02614 fmp += fmxtra;
02615 top += toxtra;
02616 }
02617 break;
02618 }
02619 case 2:
02620 {
02621 uint16 *fmp,*top;
02622 fmp = FmBits;
02623 top = ToBits;
02624 for(y=toh;y--;)
02625 {
02626 for(x=tow;x--;)
02627 {
02628 *top++ = *fmp;
02629 fmp += fmstep;
02630 }
02631 fmp += fmxtra;
02632 top += toxtra;
02633 }
02634 break;
02635 }
02636 case 4:
02637 {
02638 uint32 *fmp,*top;
02639 fmp = FmBits;
02640 top = ToBits;
02641 for(y=toh;y--;)
02642 {
02643 for(x=tow;x--;)
02644 {
02645 *top++ = *fmp;
02646 fmp += fmstep;
02647 }
02648 fmp += fmxtra;
02649 top += toxtra;
02650 }
02651 break;
02652 }
02653 case 3:
02654 {
02655 uint8 *fmp,*top;
02656 fmp = FmBits;
02657 top = ToBits;
02658 fmstep = (fmstep - 1) * 3;
02659 fmxtra *= 3;
02660 toxtra *= 3;
02661 for(y=toh;y--;)
02662 {
02663 for(x=tow;x--;)
02664 {
02665 *top++ = *fmp++;
02666 *top++ = *fmp++;
02667 *top++ = *fmp++;
02668 fmp += fmstep;
02669 }
02670 fmp += fmxtra;
02671 top += toxtra;
02672 }
02673 break;
02674 }
02675 }
02676 }
02677
02678 return GE_TRUE;
02679 }
02680
02681 GENESISAPI geBoolean GENESISCC geBitmap_ClearMips(geBitmap *Bmp)
02682 {
02683 int mip;
02684 DRV_Driver * Driver;
02685
02686
02687
02688 assert( geBitmap_IsValid(Bmp) );
02689
02690 if ( Bmp->LockOwner || Bmp->LockCount || Bmp->DataOwner )
02691 return GE_FALSE;
02692
02693 if ( Bmp->SeekMipCount == 0 && Bmp->Info.MaximumMip == 0 )
02694 return GE_TRUE;
02695
02696 Driver = Bmp->Driver;
02697 if ( Driver )
02698 {
02699 if ( ! geBitmap_DetachDriver(Bmp,GE_TRUE) )
02700 return GE_FALSE;
02701 }
02702 assert(Bmp->Driver == NULL);
02703
02704 mip = Bmp->Info.MinimumMip;
02705 if ( mip == 0 )
02706 mip++;
02707
02708 Bmp->SeekMipCount = mip;
02709
02710 for( ; mip <= Bmp->Info.MaximumMip ; mip++)
02711 {
02712 if ( Bmp->Data[mip] )
02713 {
02714 geRam_Free( Bmp->Data[mip] );
02715 Bmp->Data[mip] = NULL;
02716 }
02717 }
02718
02719 Bmp->Info.MaximumMip = Bmp->Info.MinimumMip;
02720
02721 if ( Driver )
02722 {
02723 if ( ! geBitmap_AttachToDriver(Bmp,Driver,0) )
02724 return GE_FALSE;
02725 }
02726
02727 return GE_TRUE;
02728 }
02729
02730 GENESISAPI geBoolean GENESISCC geBitmap_SetMipCount(geBitmap *Bmp,int Count)
02731 {
02732 DRV_Driver * Driver;
02733
02734 assert( geBitmap_IsValid(Bmp) );
02735
02736 if ( Bmp->LockOwner || Bmp->LockCount || Bmp->DataOwner )
02737 return GE_FALSE;
02738
02739 if ( Bmp->SeekMipCount == Count )
02740 {
02741 Driver = NULL;
02742 }
02743 else
02744 {
02745 Driver = Bmp->Driver;
02746 if ( Driver )
02747 {
02748 if ( ! geBitmap_DetachDriver(Bmp,GE_TRUE) )
02749 return GE_FALSE;
02750 }
02751 assert(Bmp->Driver == NULL);
02752 }
02753
02754 Bmp->SeekMipCount = Count;
02755
02756
02757
02758
02759
02760
02761 if ( Driver )
02762 {
02763 if ( ! geBitmap_AttachToDriver(Bmp,Driver,0) )
02764 return GE_FALSE;
02765 }
02766
02767 return GE_TRUE;
02768 }
02769
02770 geBoolean geBitmap_MakeSystemMips(geBitmap *Bmp,int low,int high)
02771 {
02772 int mip;
02773
02774 assert( geBitmap_IsValid(Bmp) );
02775
02776
02777
02778 if ( Bmp->LockOwner )
02779 Bmp = Bmp->LockOwner;
02780
02781
02782 if ( Bmp->DataOwner )
02783 return GE_FALSE;
02784
02785
02786 if ( gePixelFormat_BytesPerPel(Bmp->Info.Format) < 1 )
02787 return GE_TRUE;
02788
02789 if ( low < 0 || high >= MAXMIPLEVELS || low > high )
02790 return GE_FALSE;
02791
02792 for( mip = low; mip <= high; mip++)
02793 {
02794 if ( ! Bmp->Data[mip] )
02795 {
02796 if ( ! geBitmap_AllocSystemMip(Bmp,mip) )
02797 return GE_FALSE;
02798
02799 if ( mip != 0 )
02800 {
02801 if ( ! geBitmap_UpdateMips_System(Bmp,mip-1,mip) )
02802 return GE_FALSE;
02803 }
02804 }
02805 }
02806
02807 Bmp->Info.MinimumMip = min(Bmp->Info.MinimumMip,low);
02808 Bmp->Info.MaximumMip = max(Bmp->Info.MaximumMip,high);
02809
02810 return GE_TRUE;
02811 }
02812
02813
02814
02815 GENESISAPI uint32 GENESISCC geBitmap_MipBytes(const geBitmap *Bmp,int mip)
02816 {
02817 uint32 bytes;
02818 if ( ! Bmp )
02819 return 0;
02820 bytes = gePixelFormat_BytesPerPel(Bmp->Info.Format) *
02821 SHIFT_R_ROUNDUP(Bmp->Info.Stride,mip) *
02822 SHIFT_R_ROUNDUP(Bmp->Info.Height,mip);
02823 return bytes;
02824 }
02825
02826 GENESISAPI geBoolean GENESISCC geBitmap_GetInfo(const geBitmap *Bmp, geBitmap_Info *Info, geBitmap_Info *SecondaryInfo)
02827 {
02828 assert( geBitmap_IsValid(Bmp) );
02829
02830 assert(Info);
02831
02832 if ( Bmp->DriverHandle )
02833 {
02834 *Info = Bmp->DriverInfo;
02835 }
02836 else
02837 {
02838 *Info = Bmp->Info;
02839 }
02840
02841 if ( SecondaryInfo )
02842 *SecondaryInfo = Bmp->Info;
02843
02844 return GE_TRUE;
02845 }
02846
02847 geBoolean geBitmap_MakeDriverLockInfo(geBitmap *Bmp,int mip,geBitmap_Info *Into)
02848 {
02849 geRDriver_THandleInfo TInfo;
02850
02851
02852
02853
02854 assert(Bmp && Into);
02855
02856 if ( ! Bmp->DriverHandle || ! Bmp->Driver || mip < Bmp->DriverInfo.MinimumMip || mip > Bmp->DriverInfo.MaximumMip )
02857 return GE_FALSE;
02858
02859 if ( ! Bmp->Driver->THandle_GetInfo(Bmp->DriverHandle,mip,&TInfo) )
02860 {
02861 geErrorLog_AddString(-1,"MakeDriverLockInfo : THandle_GetInfo", NULL);
02862 return GE_FALSE;
02863 }
02864
02865 Bmp->DriverMipLock = mip;
02866 Bmp->DriverFlags = TInfo.PixelFormat.Flags;
02867
02868 Into->Width = TInfo.Width;
02869 Into->Height = TInfo.Height;
02870 Into->Stride = TInfo.Stride;
02871 Into->Format = TInfo.PixelFormat.PixelFormat;
02872 Into->ColorKey = TInfo.ColorKey;
02873
02874 if ( TInfo.Flags & RDRIVER_THANDLE_HAS_COLORKEY )
02875 Into->HasColorKey = GE_TRUE;
02876 else
02877 Into->HasColorKey = GE_FALSE;
02878
02879 Into->MinimumMip = Into->MaximumMip = mip;
02880
02881 if ( gePixelFormat_HasPalette(Into->Format) && Into->Palette && Into->Palette->HasColorKey )
02882 {
02883 Into->HasColorKey = GE_TRUE;
02884 Into->ColorKey = Into->Palette->ColorKeyIndex;
02885 }
02886
02887 return GE_TRUE;
02888 }
02889
02890 GENESISAPI int GENESISCC geBitmap_Width(const geBitmap *Bmp)
02891 {
02892 assert(Bmp);
02893 return(Bmp->Info.Width);
02894 }
02895
02896 GENESISAPI int GENESISCC geBitmap_Height(const geBitmap *Bmp)
02897 {
02898 assert(Bmp);
02899 return(Bmp->Info.Height);
02900 }
02901
02902 GENESISAPI geBoolean GENESISCC geBitmap_Blit(const geBitmap *Src, int SrcPositionX, int SrcPositionY,
02903 geBitmap *Dst, int DstPositionX, int DstPositionY,
02904 int SizeX, int SizeY )
02905 {
02906 assert( geBitmap_IsValid(Src) );
02907 assert( geBitmap_IsValid(Dst) );
02908 return geBitmap_BlitMipRect(Src,0,SrcPositionX,SrcPositionY,
02909 Dst,0,DstPositionX,DstPositionY,
02910 SizeX,SizeY);
02911 }
02912
02913 GENESISAPI geBoolean GENESISCC geBitmap_BlitBitmap(const geBitmap * Src, geBitmap * Dst )
02914 {
02915 assert( geBitmap_IsValid(Src) );
02916 assert( geBitmap_IsValid(Dst) );
02917 assert( Src != Dst );
02918 return geBitmap_BlitMipRect(Src,0,0,0,Dst,0,0,0,-1,-1);
02919 }
02920
02921 GENESISAPI geBoolean GENESISCC geBitmap_BlitBestMip(const geBitmap * Src, geBitmap * Dst )
02922 {
02923 int Width,Mip;
02924 assert( geBitmap_IsValid(Src) );
02925 assert( geBitmap_IsValid(Dst) );
02926 assert( Src != Dst );
02927 for(Mip=0; (Width = SHIFT_R_ROUNDUP(Src->Info.Width,Mip)) > Dst->Info.Width ; Mip++) ;
02928 return geBitmap_BlitMipRect(Src,Mip,0,0,Dst,0,0,0,-1,-1);
02929 }
02930
02931 GENESISAPI geBoolean GENESISCC geBitmap_BlitMip(const geBitmap * Src, int SrcMip, geBitmap * Dst, int DstMip )
02932 {
02933 assert( geBitmap_IsValid(Src) );
02934 assert( geBitmap_IsValid(Dst) );
02935 return geBitmap_BlitMipRect(Src,SrcMip,0,0,Dst,DstMip,0,0,-1,-1);
02936 }
02937
02938 geBoolean geBitmap_BlitMipRect(const geBitmap * Src, int SrcMip, int SrcX,int SrcY,
02939 geBitmap * Dst, int DstMip, int DstX,int DstY,
02940 int SizeX,int SizeY)
02941 {
02942 geBitmap * SrcLock=NULL,* DstLock=NULL;
02943 geBoolean SrcUnLock,DstUnLock;
02944 geBitmap_Info *SrcLockInfo,*DstLockInfo;
02945 uint8 *SrcBits,*DstBits;
02946
02947 assert(Src && Dst);
02948 assert( Src != Dst );
02949
02950
02951 SrcUnLock = DstUnLock = GE_FALSE;
02952
02953 if ( Src->LockOwner )
02954 {
02955 assert( Src->LockOwner->LockCount );
02956 if ( SrcMip != 0 )
02957 {
02958 geErrorLog_AddString(-1,"BlitMipRect : Src is a lock and mip != 0", NULL);
02959 goto fail;
02960 }
02961
02962 SrcLock = (geBitmap *)Src;
02963 }
02964 else
02965 {
02966 if ( ! geBitmap_LockForReadNative((geBitmap *)Src,&SrcLock,SrcMip,SrcMip) )
02967 {
02968 geErrorLog_AddString(-1,"BlitMipRect : LockForReadNative", NULL);
02969 goto fail;
02970 }
02971 SrcUnLock = GE_TRUE;
02972 }
02973
02974 if ( Dst->LockOwner )
02975 {
02976 if ( DstMip != 0 )
02977 goto fail;
02978
02979
02980
02981 DstLock = Dst;
02982 }
02983 else
02984 {
02985 if ( ! geBitmap_LockForWrite(Dst,&DstLock,DstMip,DstMip) )
02986 {
02987 geErrorLog_AddString(-1,"BlitMipRect : LockForWrite", NULL);
02988 goto fail;
02989 }
02990 DstUnLock = GE_TRUE;
02991 }
02992
02993 Src = Dst = NULL;
02994
02995 if ( SrcLock->DriverHandle )
02996 SrcLockInfo = &(SrcLock->DriverInfo);
02997 else
02998 SrcLockInfo = &(SrcLock->Info);
02999
03000 if ( DstLock->DriverHandle )
03001 DstLockInfo = &(DstLock->DriverInfo);
03002 else
03003 DstLockInfo = &(DstLock->Info);
03004
03005 if ( ! (SrcBits = geBitmap_GetBits(SrcLock)) ||
03006 ! (DstBits = geBitmap_GetBits(DstLock)) )
03007 {
03008 geErrorLog_AddString(-1,"BlitMipRect : GetBits", NULL);
03009 goto fail;
03010 }
03011
03012 if ( SizeX < 0 )
03013 SizeX = min(SrcLockInfo->Width,DstLockInfo->Width);
03014 if ( SizeY < 0 )
03015 SizeY = min(SrcLockInfo->Height,DstLockInfo->Height);
03016
03017 if (( (SrcX + SizeX) > SrcLockInfo->Width ) ||
03018 ( (SrcY + SizeY) > SrcLockInfo->Height) ||
03019 ( (DstX + SizeX) > DstLockInfo->Width ) ||
03020 ( (DstY + SizeY) > DstLockInfo->Height))
03021 {
03022 geErrorLog_AddString(-1,"BlitMipRect : dimensions bad", NULL);
03023 goto fail;
03024 }
03025
03026 SrcBits += gePixelFormat_BytesPerPel(SrcLockInfo->Format) * ( SrcY * SrcLockInfo->Stride + SrcX );
03027 DstBits += gePixelFormat_BytesPerPel(DstLockInfo->Format) * ( DstY * DstLockInfo->Stride + DstX );
03028
03029
03030 if ( ! geBitmap_BlitData( SrcLockInfo,SrcBits,SrcLock,
03031 DstLockInfo,DstBits,DstLock,
03032 SizeX,SizeY) )
03033 {
03034 goto fail;
03035 }
03036
03037 if ( SrcUnLock ) geBitmap_UnLock(SrcLock);
03038 if ( DstUnLock ) geBitmap_UnLock(DstLock);
03039
03040 return GE_TRUE;
03041
03042 fail:
03043
03044 if ( SrcUnLock ) geBitmap_UnLock(SrcLock);
03045 if ( DstUnLock ) geBitmap_UnLock(DstLock);
03046
03047 return GE_FALSE;
03048 }
03049
03050 GENESISAPI geBoolean GENESISCC geBitmap_SetFormatMin(geBitmap *Bmp,gePixelFormat NewFormat)
03051 {
03052 geBitmap_Palette * Pal;
03053
03054 assert(geBitmap_IsValid(Bmp));
03055
03056 Pal = geBitmap_GetPalette(Bmp);
03057 if ( Bmp->Info.HasColorKey )
03058 {
03059 uint32 CK=0;
03060 if ( gePixelFormat_IsRaw(NewFormat) )
03061 {
03062 if ( gePixelFormat_IsRaw(Bmp->Info.Format) )
03063 {
03064 CK = gePixelFormat_ConvertPixel(Bmp->Info.Format,Bmp->Info.ColorKey,NewFormat);
03065 }
03066 else if ( gePixelFormat_HasPalette(Bmp->Info.Format) )
03067 {
03068 assert(Pal);
03069 geBitmap_Palette_GetEntry(Pal,Bmp->Info.ColorKey,&CK);
03070 CK = gePixelFormat_ConvertPixel(Pal->Format,CK,NewFormat);
03071 if ( ! CK ) CK = 1;
03072 }
03073 }
03074 else
03075 {
03076 if ( gePixelFormat_HasPalette(NewFormat) )
03077 {
03078 CK = 255;
03079 }
03080 else
03081 {
03082 CK = 1;
03083 }
03084 }
03085
03086 return geBitmap_SetFormat(Bmp,NewFormat,GE_TRUE,CK,Pal);
03087 }
03088 else
03089 {
03090 return geBitmap_SetFormat(Bmp,NewFormat,GE_FALSE,0,Pal);
03091 }
03092 }
03093
03094 GENESISAPI geBoolean GENESISCC geBitmap_SetFormat(geBitmap *Bmp,
03095 gePixelFormat NewFormat,
03096 geBoolean HasColorKey, uint32 ColorKey,
03097 const geBitmap_Palette *Palette )
03098 {
03099 assert( geBitmap_IsValid(Bmp) );
03100
03101 if ( Bmp->LockOwner || Bmp->LockCount || Bmp->DataOwner )
03102 {
03103 geErrorLog_AddString(-1,"SetFormat : not an original bitmap", NULL);
03104 return GE_FALSE;
03105 }
03106
03107
03108
03109
03110 if ( NewFormat == GE_PIXELFORMAT_WAVELET )
03111 {
03112 geErrorLog_AddString(-1,"Genesis3D 1.0 does not support Wavelet Images",NULL);
03113 return GE_FALSE;
03114 }
03115
03116 if ( NewFormat == Bmp->Info.Format )
03117 {
03118
03119
03120 if ( gePixelFormat_HasPalette(NewFormat) && Palette )
03121 {
03122 if ( ! geBitmap_SetPalette(Bmp,(geBitmap_Palette *)Palette) )
03123 return GE_FALSE;
03124 }
03125
03126 if ( (! HasColorKey )
03127 || ( HasColorKey && Bmp->Info.HasColorKey && ColorKey == Bmp->Info.ColorKey ) )
03128 {
03129 Bmp->Info.HasColorKey = HasColorKey;
03130 Bmp->Info.ColorKey = ColorKey;
03131 return GE_TRUE;
03132 }
03133 else
03134 {
03135 geBitmap_Info OldInfo;
03136
03137 OldInfo = Bmp->Info;
03138
03139 assert(HasColorKey);
03140
03141
03142
03143 Bmp->Info.HasColorKey = HasColorKey;
03144 Bmp->Info.ColorKey = ColorKey;
03145
03146 if ( Bmp->Data[Bmp->Info.MinimumMip] == NULL )
03147 return GE_TRUE;
03148
03149 assert(Bmp->Info.MinimumMip == 0);
03150
03151
03152 if ( ! geBitmap_BlitData( &OldInfo, Bmp->Data[Bmp->Info.MinimumMip], NULL,
03153 &(Bmp->Info), Bmp->Data[Bmp->Info.MinimumMip], NULL,
03154 Bmp->Info.Width, Bmp->Info.Height) )
03155 {
03156 return GE_FALSE;
03157 }
03158
03159 return GE_TRUE;
03160 }
03161 }
03162 else
03163 {
03164 geBitmap_Info OldInfo;
03165 int OldBPP,NewBPP;
03166 int OldMaxMips;
03167 DRV_Driver * Driver;
03168
03169 if ( gePixelFormat_HasPalette(NewFormat) )
03170 {
03171 if ( Palette )
03172 {
03173 if ( ! geBitmap_SetPalette(Bmp,(geBitmap_Palette *)Palette) )
03174 return GE_FALSE;
03175 }
03176 else
03177 {
03178 if ( ! geBitmap_GetPalette(Bmp) && ! gePixelFormat_HasPalette(Bmp->Info.Format) )
03179 {
03180 geBitmap_Palette *NewPal;
03181 NewPal = geBitmap_Palette_CreateFromBitmap(Bmp,GE_FALSE);
03182 if ( ! NewPal )
03183 {
03184 geErrorLog_AddString(-1,"_SetFormat : createPaletteFromBitmap failed", NULL);
03185 return GE_FALSE;
03186 }
03187 if ( ! geBitmap_SetPalette(Bmp,NewPal) )
03188 return GE_FALSE;
03189 geBitmap_Palette_Destroy(&NewPal);
03190 }
03191 }
03192 }
03193
03194 Driver = Bmp->Driver;
03195 if ( Driver )
03196 if ( ! geBitmap_DetachDriver(Bmp,GE_TRUE) )
03197 return GE_FALSE;
03198
03199 OldBPP = gePixelFormat_BytesPerPel(Bmp->Info.Format);
03200 NewBPP = gePixelFormat_BytesPerPel(NewFormat);
03201
03202 OldInfo = Bmp->Info;
03203 Bmp->Info.Format = NewFormat;
03204 Bmp->Info.HasColorKey = HasColorKey;
03205 Bmp->Info.ColorKey = ColorKey;
03206
03207
03208 OldMaxMips = max(Bmp->Info.MaximumMip,Bmp->DriverInfo.MaximumMip);
03209 geBitmap_ClearMips(Bmp);
03210
03211 if ( Bmp->Data[Bmp->Info.MinimumMip] == NULL &&
03212 Bmp->DriverHandle == NULL )
03213 return GE_TRUE;
03214
03215 if ( OldBPP == NewBPP )
03216 {
03217 geBitmap * Lock;
03218 void * Bits;
03219
03220 if ( ! geBitmap_LockForWrite(Bmp,&Lock,0,0) )
03221 return GE_FALSE;
03222
03223 if ( ! (Bits = geBitmap_GetBits(Lock)) )
03224 {
03225 geBitmap_UnLock(Lock);
03226 return GE_FALSE;
03227 }
03228
03229
03230 if ( ! geBitmap_BlitData( &OldInfo, Bits, Lock,
03231 &(Lock->Info), Bits, Lock,
03232 Lock->Info.Width, Lock->Info.Height) )
03233 {
03234 geBitmap_UnLock(Lock);
03235 return GE_FALSE;
03236 }
03237
03238 geBitmap_UnLock(Lock);
03239 }
03240 else
03241 {
03242 geBitmap OldBmp;
03243 geBitmap *Lock,*SrcLock;
03244 void *Bits,*OldBits;
03245
03246 OldBmp = *Bmp;
03247 OldBmp.Info = OldInfo;
03248
03249
03250 Bmp->Info.Stride = Bmp->Info.Width;
03251 Bmp->Data[0] = NULL;
03252 Bmp->Alpha = NULL;
03253
03254 if ( ! geBitmap_AllocSystemMip(Bmp,0) )
03255 return GE_FALSE;
03256
03257 if ( ! geBitmap_LockForReadNative(&OldBmp,&SrcLock,0,0) )
03258 return GE_FALSE;
03259
03260 if ( ! geBitmap_LockForWrite(Bmp,&Lock,0,0) )
03261 return GE_FALSE;
03262
03263 if ( ! (Bits = geBitmap_GetBits(Lock)) )
03264 {
03265 geBitmap_UnLock(Lock);
03266 return GE_FALSE;
03267 }
03268 if ( ! (OldBits = geBitmap_GetBits(SrcLock)) )
03269 {
03270 geBitmap_UnLock(Lock);
03271 return GE_FALSE;
03272 }
03273
03274
03275 if ( ! geBitmap_BlitData( &OldInfo, OldBits, SrcLock,
03276 &(Lock->Info), Bits, Lock,
03277 Lock->Info.Width, Lock->Info.Height) )
03278 {
03279
03280 return GE_FALSE;
03281 }
03282
03283 geBitmap_UnLock(Lock);
03284 geBitmap_UnLock(SrcLock);
03285
03286 if ( OldBmp.Data[0] )
03287 {
03288 geRam_Free(OldBmp.Data[0]);
03289 OldBmp.Data[0] = NULL;
03290 }
03291
03292 if ( gePixelFormat_HasGoodAlpha(NewFormat) )
03293 {
03294 geBitmap_Destroy(&(OldBmp.Alpha));
03295 }
03296 else
03297 {
03298 Bmp->Alpha = OldBmp.Alpha;
03299 }
03300 }
03301
03302 {
03303 int mip;
03304 mip = Bmp->Info.MinimumMip;
03305 while( mip < OldMaxMips )
03306 {
03307 geBitmap_UpdateMips(Bmp,mip,mip+1);
03308 mip++;
03309 }
03310 }
03311
03312 if ( Driver )
03313 {
03314 if ( ! geBitmap_AttachToDriver(Bmp,Driver,0) )
03315 return GE_FALSE;
03316 }
03317 }
03318
03319 return GE_TRUE;
03320 }
03321
03322 GENESISAPI geBoolean GENESISCC geBitmap_SetColorKey(geBitmap *Bmp, geBoolean HasColorKey, uint32 ColorKey , geBoolean Smart)
03323 {
03324 assert( geBitmap_IsValid(Bmp) );
03325
03326 if ( Bmp->LockOwner || Bmp->LockCount || Bmp->DataOwner )
03327 {
03328 geErrorLog_AddString(-1,"SetColorKey : not an original bitmap", NULL);
03329 return GE_FALSE;
03330 }
03331
03332
03333
03334 if ( Bmp->DriverHandle )
03335 geBitmap_Update_DriverToSystem(Bmp);
03336
03337 if ( HasColorKey &&
03338 ((uint32)ColorKey>>1) >= ((uint32)1<<(gePixelFormat_BytesPerPel(Bmp->Info.Format)*8 - 1)) )
03339 {
03340 geErrorLog_AddString(-1,"geBitmap_SetColorKey : invalid ColorKey pixel!", NULL);
03341 return GE_FALSE;
03342 }
03343 if ( HasColorKey && gePixelFormat_HasAlpha(Bmp->Info.Format) )
03344 {
03345 geErrorLog_AddString(-1,"geBitmap_SetColorKey : non-fatal : Alpha and ColorKey together won't work right", NULL);
03346 }
03347
03348 if ( HasColorKey && Smart && Bmp->Data[0] )
03349 {
03350 Bmp->Info.HasColorKey = GE_TRUE;
03351 Bmp->Info.ColorKey = ColorKey;
03352 if ( ! geBitmap_UsesColorKey(Bmp) )
03353 {
03354 Bmp->Info.HasColorKey = GE_FALSE;
03355 Bmp->Info.ColorKey = 1;
03356 }
03357 }
03358 else
03359 {
03360 Bmp->Info.HasColorKey = HasColorKey;
03361 Bmp->Info.ColorKey = ColorKey;
03362 }
03363
03364 if ( Bmp->DriverHandle )
03365 geBitmap_Update_SystemToDriver(Bmp);
03366
03367 return GE_TRUE;
03368 }
03369
03370 geBoolean geBitmap_UsesColorKey(const geBitmap * Bmp)
03371 {
03372 void * Bits;
03373 const gePixelFormat_Operations * ops;
03374 int x,y,w,h,s;
03375 uint32 pel,ColorKey;
03376
03377 if ( ! Bmp->Info.HasColorKey )
03378 return GE_FALSE;
03379
03380 if ( ! Bmp->Data[0] )
03381 {
03382 geErrorLog_AddString(-1,"UsesColorKey : no data!", NULL);
03383 return GE_TRUE;
03384 }
03385
03386 assert( Bmp->Info.MinimumMip == 0 );
03387
03388 Bits = Bmp->Data[0];
03389 ops = gePixelFormat_GetOperations(Bmp->Info.Format);
03390 assert(ops);
03391
03392 w = Bmp->Info.Width;
03393 h = Bmp->Info.Height;
03394 s = Bmp->Info.Stride;
03395
03396 ColorKey = Bmp->Info.ColorKey;
03397
03398 switch(ops->BytesPerPel)
03399 {
03400 case 0:
03401 geErrorLog_AddString(-1,"UsesColorKey : invalid format", NULL);
03402 return GE_TRUE;
03403
03404
03405
03406
03407
03408
03409 case 1:
03410 {
03411 uint8 * ptr;
03412 ptr = Bits;
03413 for(y=h;y--;)
03414 {
03415 for(x=w;x--;)
03416 {
03417 pel = *ptr++;
03418 if ( pel == ColorKey )
03419 {
03420 return GE_TRUE;
03421 }
03422 }
03423 ptr += (s-w);
03424 }
03425 break;
03426 }
03427 case 2:
03428 {
03429 uint16 * ptr;
03430 ptr = Bits;
03431 for(y=h;y--;)
03432 {
03433 for(x=w;x--;)
03434 {
03435 pel = *ptr++;
03436 if ( pel == ColorKey )
03437 {
03438 return GE_TRUE;
03439 }
03440 }
03441 ptr += (s-w);
03442 }
03443 break;
03444 }
03445
03446 case 3:
03447 {
03448 uint8 * ptr;
03449 uint8 ckR, ckG, ckB;
03450
03451 ckB = (uint8) (ColorKey & 0x000000ff);
03452 ckG = (uint8) ((ColorKey >> 8) & 0x000000ff);
03453 ckR = (uint8) ((ColorKey >> 16) & 0x000000ff);
03454 ptr = Bits;
03455 for(y=h;y--;)
03456 {
03457 for(x=w;x--;)
03458 {
03459 if ((*ptr == ckR) && (*(ptr+1) == ckG) && (*(ptr+2) == ckB))
03460 {
03461 return GE_TRUE;
03462 }
03463 ptr += 3;
03464 }
03465 ptr += ((s-w)*3);
03466 }
03467 break;
03468 }
03469
03470 case 4:
03471 {
03472 uint32 * ptr;
03473 ptr = Bits;
03474 for(y=h;y--;)
03475 {
03476 for(x=w;x--;)
03477 {
03478 pel = *ptr++;
03479 if ( pel == ColorKey )
03480 {
03481 return GE_TRUE;
03482 }
03483 }
03484 ptr += (s-w);
03485 }
03486 break;
03487 }
03488 }
03489 return GE_FALSE;
03490 }
03491
03492
03493 GENESISAPI geBoolean GENESISCC geBitmap_SetPalette(geBitmap *Bmp, const geBitmap_Palette *Palette)
03494 {
03495 assert(Bmp);
03496 assert( geBitmap_Palette_IsValid(Palette) );
03497
03498 if ( Bmp->LockOwner )
03499 Bmp = Bmp->LockOwner;
03500
03501
03502
03503
03504
03505
03506
03507
03508
03509
03510
03511
03512
03513
03514 if ( Bmp->Info.Palette != Palette )
03515 {
03516
03517 if ( Palette->Driver )
03518 {
03519 if ( ! geBitmap_AllocPalette(Bmp,Palette->Format,NULL) )
03520 return GE_FALSE;
03521
03522 if ( ! geBitmap_Palette_Copy(Palette,Bmp->Info.Palette) )
03523 return GE_FALSE;
03524 }
03525 else
03526 {
03527 if ( Bmp->Info.Palette )
03528 geBitmap_Palette_Destroy(&(Bmp->Info.Palette));
03529
03530 Bmp->Info.Palette = (geBitmap_Palette *)Palette;
03531 geBitmap_Palette_CreateRef(Bmp->Info.Palette);
03532 }
03533 }
03534
03535 if ( gePixelFormat_HasPalette(Bmp->DriverInfo.Format) &&
03536 Bmp->DriverInfo.Palette != Palette )
03537 {
03538 if ( Palette->Driver == Bmp->Driver &&
03539 ( ! Palette->HasColorKey || ! Bmp->DriverInfo.ColorKey ||
03540 (uint32)Palette->ColorKeyIndex == Bmp->DriverInfo.ColorKey ) )
03541 {
03542 if ( Bmp->DriverInfo.Palette )
03543 geBitmap_Palette_Destroy(&(Bmp->DriverInfo.Palette));
03544 Bmp->DriverInfo.Palette = (geBitmap_Palette *)Palette;
03545 geBitmap_Palette_CreateRef(Bmp->DriverInfo.Palette);
03546 }
03547 else if ( Bmp->DriverInfo.Palette )
03548 {
03549 if ( ! geBitmap_Palette_Copy(Palette,Bmp->DriverInfo.Palette) )
03550 return GE_FALSE;
03551 }
03552 else
03553 {
03554 if ( ! geBitmap_AllocPalette(Bmp,0,Bmp->Driver) )
03555 return GE_FALSE;
03556
03557 if ( ! geBitmap_Palette_Copy(Palette,Bmp->DriverInfo.Palette) )
03558 return GE_FALSE;
03559 }
03560 }
03561
03562 if ( Bmp->DriverHandle )
03563 {
03564
03565 if ( gePixelFormat_HasPalette(Bmp->Info.Format) &&
03566 ! gePixelFormat_HasPalette(Bmp->DriverInfo.Format) )
03567 {
03568
03569 Bmp->DriverDataChanged = GE_FALSE;
03570 if ( ! geBitmap_Update_SystemToDriver(Bmp) )
03571 return GE_FALSE;
03572 }
03573 else if ( ! gePixelFormat_HasPalette(Bmp->Info.Format) &&
03574 gePixelFormat_HasPalette(Bmp->DriverInfo.Format) )
03575 {
03576 Bmp->DriverDataChanged = GE_TRUE;
03577 }
03578 }
03579
03580 assert( geBitmap_IsValid(Bmp) );
03581
03582 return GE_TRUE;
03583 }
03584
03585 GENESISAPI geBitmap_Palette * GENESISCC geBitmap_GetPalette(const geBitmap *Bmp)
03586 {
03587 if ( ! Bmp ) return NULL;
03588
03589 if ( Bmp->Driver && Bmp->DriverInfo.Palette )
03590 {
03591 assert(Bmp->Info.Palette);
03592 return Bmp->DriverInfo.Palette;
03593 }
03594
03595 return Bmp->Info.Palette;
03596 }
03597
03598
03599 GENESISAPI geBitmap * GENESISCC geBitmap_GetAlpha(const geBitmap *Bmp)
03600 {
03601 if ( ! Bmp ) return NULL;
03602 return Bmp->Alpha;
03603 }
03604
03605 GENESISAPI geBoolean GENESISCC geBitmap_SetAlpha(geBitmap *Bmp, const geBitmap *AlphaBmp)
03606 {
03607 assert( geBitmap_IsValid(Bmp) );
03608
03609 if ( Bmp->LockOwner )
03610 Bmp = Bmp->LockOwner;
03611 if ( Bmp->LockCount > 0 || Bmp->DataOwner )
03612 {
03613 geErrorLog_AddString(-1,"SetAlpha : not an original bitmap", NULL);
03614 return GE_FALSE;
03615 }
03616
03617 if ( AlphaBmp == Bmp->Alpha )
03618 return GE_TRUE;
03619
03620 if ( Bmp->DriverHandle )
03621 {
03622 geBitmap_Update_DriverToSystem(Bmp);
03623 }
03624
03625 if ( Bmp->Alpha )
03626 {
03627 geBitmap_Destroy(&(Bmp->Alpha));
03628 }
03629
03630 Bmp->Alpha = (geBitmap *)AlphaBmp;
03631 if ( AlphaBmp )
03632 {
03633 assert( geBitmap_IsValid(AlphaBmp) );
03634 geBitmap_CreateRef(Bmp->Alpha);
03635 }
03636
03637 if ( Bmp->DriverHandle )
03638 {
03639
03640 geBitmap_Update_SystemToDriver(Bmp);
03641 }
03642
03643 return GE_TRUE;
03644 }
03645
03646 GENESISAPI geBoolean GENESISCC geBitmap_SetPreferredFormat(geBitmap *Bmp,gePixelFormat Format)
03647 {
03648
03649 if ( Bmp->LockOwner )
03650 Bmp = Bmp->LockOwner;
03651 if ( Bmp->LockCount > 0 || Bmp->DataOwner )
03652 {
03653 geErrorLog_AddString(-1,"SetPrefferedFormat : not an original bitmap", NULL);
03654 return GE_FALSE;
03655 }
03656
03657 if ( Bmp->PreferredFormat != Format )
03658 {
03659 DRV_Driver * Driver;
03660 Bmp->PreferredFormat = Format;
03661 Driver = Bmp->Driver;
03662 if ( Driver )
03663 {
03664 if ( ! geBitmap_DetachDriver(Bmp,GE_TRUE) )
03665 return GE_FALSE;
03666 if ( ! geBitmap_AttachToDriver(Bmp,Driver,0) )
03667 return GE_FALSE;
03668 }
03669 }
03670
03671 return GE_TRUE;
03672 }
03673
03674 GENESISAPI gePixelFormat GENESISCC geBitmap_GetPreferredFormat(const geBitmap *Bmp)
03675 {
03676 if ( ! Bmp ) return 0;
03677 return Bmp->PreferredFormat;
03678 }
03679
03680
03681
03682 GENESISAPI geBitmap * GENESISCC geBitmap_CreateFromFileName(const geVFile *BaseFS,const char *Name)
03683 {
03684 geVFile * File;
03685 geBitmap * Bitmap;
03686
03687
03688 if ( BaseFS )
03689 {
03690 File = geVFile_Open((geVFile *)BaseFS, Name, GE_VFILE_OPEN_READONLY);
03691 }
03692 else
03693 {
03694 File = geVFile_OpenNewSystem(NULL,GE_VFILE_TYPE_DOS,Name,NULL,GE_VFILE_OPEN_READONLY);
03695 }
03696 if ( ! File )
03697 return NULL;
03698
03699 Bitmap = geBitmap_CreateFromFile(File);
03700 geVFile_Close(File);
03701
03702 return Bitmap;
03703 }
03704
03705 GENESISAPI geBoolean GENESISCC geBitmap_WriteToFileName(const geBitmap * Bmp,const geVFile *BaseFS,const char *Name)
03706 {
03707 geVFile * File;
03708 geBoolean Ret;
03709
03710 if ( BaseFS )
03711 {
03712 File = geVFile_Open((geVFile *)BaseFS, Name, GE_VFILE_OPEN_CREATE);
03713 }
03714 else
03715 {
03716 File = geVFile_OpenNewSystem(NULL,GE_VFILE_TYPE_DOS,Name,NULL,GE_VFILE_OPEN_CREATE);
03717 }
03718
03719 if ( ! File )
03720 return GE_FALSE;
03721
03722 Ret = geBitmap_WriteToFile(Bmp,File);
03723
03724 geVFile_Close(File);
03725
03726 return Ret;
03727 }
03728
03729
03730 typedef uint32 geBmTag_t;
03731 #define GEBM_TAG ((geBmTag_t)0x6D426547) // "GeBm"
03732
03733
03734 #define GEBM_VERSION (((uint32)GEBM_VERSION_MAJOR<<4) + (uint32)GEBM_VERSION_MINOR)
03735 #define VERSION_MAJOR(Version) (((Version)>>4)&0x0F)
03736 #define VERSION_MINOR(Version) ((Version)&0x0F)
03737
03738 #define MIP_MASK (0xF)
03739 #define MIP_FLAG_COMPRESSED (1<<4)
03740 #define MIP_FLAG_PAETH_FILTERED (1<<5)
03741
03742 static geBoolean geBitmap_ReadFromBMP(geBitmap * Bmp,geVFile * F);
03743
03744 static geBoolean geBitmap_IsTGA(geVFile * F);
03745 static geBoolean geBitmap_ReadFromTGA(geBitmap * Bmp, geVFile * File);
03746
03747 GENESISAPI geBitmap * GENESISCC geBitmap_CreateFromFile(geVFile *F)
03748 {
03749 geBitmap * Bmp;
03750 geBmTag_t Tag;
03751
03752 assert(F);
03753
03754 if ( ! geVFile_Read(F, &Tag, sizeof(Tag)) )
03755 return NULL;
03756
03757 Bmp = geBitmap_Create_Base();
03758 if ( ! Bmp )
03759 return NULL;
03760
03761 if ( Tag == GEBM_TAG )
03762 {
03763 uint8 flags;
03764 uint8 Version;
03765 int mip;
03766
03767
03768
03769 if ( ! geVFile_Read(F, &Version, sizeof(Version)) )
03770 goto fail;
03771
03772 if ( VERSION_MAJOR(Version) != VERSION_MAJOR(GEBM_VERSION) )
03773 {
03774 geErrorLog_AddString(-1,"CreateFromFile : incompatible GeBm version", NULL);
03775 goto fail;
03776 }
03777
03778 if ( ! geBitmap_ReadInfo(Bmp,F) )
03779 goto fail;
03780
03781 if ( Bmp->Info.Palette )
03782 {
03783 Bmp->Info.Palette = NULL;
03784 if ( ! ( Bmp->Info.Palette = geBitmap_Palette_CreateFromFile(F)) )
03785 goto fail;
03786 }
03787
03788 if ( Bmp->Info.Format == GE_PIXELFORMAT_WAVELET )
03789 {
03790 geErrorLog_AddString(-1,"Genesis3D 1.0 does not support Wavelet Images",NULL);
03791 }
03792 else
03793 {
03794 for(;;)
03795 {
03796 if ( ! geVFile_Read(F, &flags, sizeof(flags)) )
03797 goto fail;
03798
03799 mip = flags & MIP_MASK;
03800
03801 if ( mip > Bmp->Info.MaximumMip )
03802 break;
03803
03804 assert(mip >= Bmp->Info.MinimumMip );
03805 assert( Bmp->Info.Stride == Bmp->Info.Width );
03806
03807 if ( ! geBitmap_AllocSystemMip(Bmp,mip) )
03808 goto fail;
03809
03810 if ( flags & MIP_FLAG_COMPRESSED )
03811 {
03812 #ifdef DO_LZ
03813 geVFile * LzF;
03814
03815 LzF = geVFile_OpenNewSystem(F,GE_VFILE_TYPE_LZ,NULL,NULL,GE_VFILE_OPEN_READONLY);
03816 if ( ! LzF )
03817 {
03818 geErrorLog_AddString(-1,"Bitmap_CreateFromFile : LZ File Open failed",NULL);
03819 return GE_FALSE;
03820 }
03821
03822 if ( ! geVFile_Read(LzF, Bmp->Data[mip], geBitmap_MipBytes(Bmp,mip) ) )
03823 {
03824 geVFile_Close(LzF);
03825 geErrorLog_AddString(-1,"Bitmap_CreateFromFile : LZ File Read failed",NULL);
03826 return GE_FALSE;
03827 }
03828
03829 if ( ! geVFile_Close(LzF) )
03830 {
03831 geErrorLog_AddString(-1,"Bitmap_CreateFromFile : LZ File Close failed",NULL);
03832 return GE_FALSE;
03833 }
03834 #endif
03835 }
03836 else
03837 {
03838 if ( ! geVFile_Read(F, Bmp->Data[mip], geBitmap_MipBytes(Bmp,mip) ) )
03839 goto fail;
03840 }
03841
03842 if ( flags & MIP_FLAG_PAETH_FILTERED )
03843 {
03844 geErrorLog_AddString(-1,"Bitmap_CreateFromFile : Paeth Filter not supported in this version!",NULL);
03845 return GE_FALSE;
03846 }
03847
03848 Bmp->Modified[mip] = GE_TRUE;
03849 }
03850 }
03851
03852 if( Bmp->Alpha )
03853 {
03854 if ( ! (Bmp->Alpha = geBitmap_CreateFromFile(F)) )
03855 goto fail;
03856 }
03857 }
03858 else
03859 {
03860 if ( ! geVFile_Seek(F, - (int)sizeof(Tag), GE_VFILE_SEEKCUR) )
03861 goto fail;
03862
03863 if ( (Tag&0xFFFF) == 0x4D42 )
03864 {
03865
03866 if ( ! geBitmap_ReadFromBMP(Bmp,F) )
03867 goto fail;
03868 }
03869 else
03870 {
03871
03872
03873 if (geBitmap_IsTGA(F))
03874 {
03875 if( ! geBitmap_ReadFromTGA(Bmp, F))
03876 goto fail;
03877 }
03878 else
03879
03880 goto fail;
03881
03882 }
03883 }
03884
03885 return Bmp;
03886
03887 fail:
03888 assert(Bmp);
03889
03890 geBitmap_Destroy(&Bmp);
03891 return NULL;
03892 }
03893
03894 GENESISAPI geBoolean GENESISCC geBitmap_WriteToFile(const geBitmap *Bmp, geVFile *F)
03895 {
03896 geBmTag_t geBM_Tag;
03897 uint8 geBM_Version;
03898 uint8 flags;
03899 int mip;
03900
03901 assert(Bmp && F);
03902 assert( geBitmap_IsValid(Bmp) );
03903
03904 geBM_Tag = GEBM_TAG;
03905 geBM_Version = GEBM_VERSION;
03906
03907 if ( Bmp->DriverHandle )
03908 {
03909 if ( ! geBitmap_Update_DriverToSystem((geBitmap *)Bmp) )
03910 {
03911 geErrorLog_AddString(-1,"WriteToFile : Update_DriverToSystem", NULL);
03912 return GE_FALSE;
03913 }
03914 }
03915
03916 if ( ! geVFile_Write(F, &geBM_Tag, sizeof(geBM_Tag)) )
03917 return GE_FALSE;
03918
03919 if ( ! geVFile_Write(F, &geBM_Version, sizeof(geBM_Version)) )
03920 return GE_FALSE;
03921
03922 if ( ! geBitmap_WriteInfo(Bmp,F) )
03923 return GE_FALSE;
03924
03925 #ifdef COUNT_HEADER_SIZES
03926 Header_Sizes += 15;
03927 #endif
03928
03929
03930 if ( Bmp->Info.Palette )
03931 {
03932 if ( ! geBitmap_Palette_WriteToFile(Bmp->Info.Palette,F) )
03933 return GE_FALSE;
03934 }
03935
03936 if ( Bmp->Info.Format == GE_PIXELFORMAT_WAVELET )
03937 {
03938 geErrorLog_AddString(-1,"Genesis3D 1.0 does not support Wavelet Images",NULL);
03939 }
03940 else
03941 {
03942 for( mip = Bmp->Info.MinimumMip; mip <= Bmp->Info.MaximumMip; mip++ )
03943 {
03944
03945
03946
03947
03948
03949 if ( (mip == Bmp->Info.MinimumMip || Bmp->Modified[mip]) && Bmp->Data[mip] )
03950 {
03951 uint8 * MipData;
03952 geBoolean MipDataAlloced;
03953 uint32 MipDataLen;
03954
03955 MipDataLen = SHIFT_R_ROUNDUP(Bmp->Info.Width,mip) * SHIFT_R_ROUNDUP(Bmp->Info.Height,mip) *
03956 gePixelFormat_BytesPerPel(Bmp->Info.Format);
03957
03958 if ( Bmp->Info.Stride == Bmp->Info.Width )
03959 {
03960 MipData = Bmp->Data[mip];
03961 MipDataAlloced = GE_FALSE;
03962 }
03963 else
03964 {
03965 int w,h,s,y;
03966 uint8 * fptr,*tptr;
03967
03968 if ( ! (MipData = geRam_Allocate(MipDataLen) ) )
03969 {
03970 geErrorLog_AddString(-1,"Bitmap_WriteToFile : Ram_Alloc failed!",NULL);
03971 return GE_FALSE;
03972 }
03973
03974 MipDataAlloced = GE_TRUE;
03975
03976 s = SHIFT_R_ROUNDUP(Bmp->Info.Stride,mip)* gePixelFormat_BytesPerPel(Bmp->Info.Format);
03977 w = SHIFT_R_ROUNDUP(Bmp->Info.Width,mip) * gePixelFormat_BytesPerPel(Bmp->Info.Format);
03978 h = SHIFT_R_ROUNDUP(Bmp->Info.Height,mip);
03979
03980 fptr = Bmp->Data[mip];
03981 tptr = MipData;
03982 for(y=h;y--;)
03983 {
03984 memcpy(tptr,fptr,w);
03985 fptr += s;
03986 tptr += w;
03987 }
03988 }
03989
03990 assert( mip <= MIP_MASK );
03991 flags = mip;
03992 #ifdef DO_LZ
03993 flags |= MIP_FLAG_COMPRESSED;
03994 #endif
03995
03996 if ( ! geVFile_Write(F, &flags, sizeof(flags)) )
03997 return GE_FALSE;
03998
03999 #ifdef DO_LZ
04000 {
04001 geVFile * LzF;
04002 LzF = geVFile_OpenNewSystem(F,GE_VFILE_TYPE_LZ,NULL,NULL,GE_VFILE_OPEN_CREATE);
04003 if ( ! LzF )
04004 {
04005 if ( MipDataAlloced )
04006 geRam_Free(MipData);
04007 geErrorLog_AddString(-1,"Bitmap_WriteToFile : LZ File Open failed",NULL);
04008 return GE_FALSE;
04009 }
04010
04011 if ( ! geVFile_Write(LzF, MipData, MipDataLen ) )
04012 return GE_FALSE;
04013
04014 if ( ! geVFile_Close(LzF) )
04015 {
04016 if ( MipDataAlloced )
04017 geRam_Free(MipData);
04018 geErrorLog_AddString(-1,"Bitmap_WriteToFile : LZ File Close failed",NULL);
04019 return GE_FALSE;
04020 }
04021 }
04022 #else
04023 if ( ! geVFile_Write(F, MipData, MipDataLen ) )
04024 return GE_FALSE;
04025 #endif
04026
04027 if ( MipDataAlloced )
04028 geRam_Free(MipData);
04029 }
04030 }
04031
04032
04033
04034 flags = MIP_MASK;
04035 if ( ! geVFile_Write(F, &flags, sizeof(flags)) )
04036 return GE_FALSE;
04037 }
04038
04039
04040
04041 if( Bmp->Alpha )
04042 {
04043 if ( ! geBitmap_WriteToFile(Bmp->Alpha,F) )
04044 return GE_FALSE;
04045 }
04046
04047 return GE_TRUE;
04048 }
04049
04050
04051
04052 #pragma pack(1)
04053
04054 typedef struct TGAHEADER
04055 {
04056 char IDLength;
04057 char ColorMapType;
04058 char ImageType;
04059 uint16 CMFirstEntry;
04060 uint16 CMLength;
04061 char CMEntrySize;
04062 uint16 Xorigin;
04063 uint16 Yorigin;
04064 uint16 Width;
04065 uint16 Height;
04066 char PixelDepth;
04067 char ImageDescriptor;
04068 } TGAHEADER;
04069
04070 typedef struct
04071 {
04072 uint32 biSize;
04073 long biWidth;
04074 long biHeight;
04075 uint16 biPlanes;
04076 uint16 biBitCount;
04077 uint32 biCompression;
04078 uint32 biSizeImage;
04079 long biXPelsPerMeter;
04080 long biYPelsPerMeter;
04081 uint32 biClrUsed;
04082 uint32 biClrImportant;
04083 } BITMAPINFOHEADER;
04084
04085 typedef struct
04086 {
04087 uint16 bfType;
04088 uint32 bfSize;
04089 uint16 bfReserved1;
04090 uint16 bfReserved2;
04091 uint32 bfOffBits;
04092 } BITMAPFILEHEADER;
04093
04094 typedef struct
04095 {
04096 uint8 B;
04097 uint8 G;
04098 uint8 R;
04099 uint8 rgbReserved;
04100 } RGBQUAD;
04101 #pragma pack()
04102
04103
04104
04105 static geBoolean geBitmap_ReadFromBMP(geBitmap * Bmp,geVFile * F)
04106 {
04107 BITMAPFILEHEADER bmfh;
04108 BITMAPINFOHEADER bmih;
04109 int bPad,myRowWidth,bmpRowWidth,pelBytes;
04110
04111
04112
04113 if ( ! geVFile_Read(F, &bmfh, sizeof(bmfh)) )
04114 return GE_FALSE;
04115
04116 assert(bmfh.bfType == 0x4D42);
04117
04118 bPad = bmfh.bfOffBits;
04119
04120 if ( ! geVFile_Read(F, &bmih, sizeof(bmih)) )
04121 return GE_FALSE;
04122
04123 if ( bmih.biSize > sizeof(bmih) )
04124 {
04125 geVFile_Seek(F, bmih.biSize - sizeof(bmih), GE_VFILE_SEEKCUR);
04126 }
04127 else if ( bmih.biSize < sizeof(bmih) )
04128 {
04129 geErrorLog_AddString(-1,"CreateFromFile : bmih size bad", NULL);
04130 return GE_FALSE;
04131 }
04132
04133 if ( bmih.biCompression )
04134 {
04135 geErrorLog_AddString(-1,"CreateFromFile : only BI_RGB BMP compression supported", NULL);
04136 return GE_FALSE;
04137 }
04138
04139 bPad -= sizeof(bmih) + sizeof(bmfh);
04140
04141 switch (bmih.biBitCount)
04142 {
04143 case 8:
04144 if ( bmih.biClrUsed == 0 ) bmih.biClrUsed = 256;
04145
04146 if ( ! (Bmp->Info.Palette = geBitmap_Palette_Create(GE_PIXELFORMAT_32BIT_XRGB,bmih.biClrUsed)) )
04147 return GE_FALSE;
04148
04149 if ( ! geVFile_Read(F, Bmp->Info.Palette->Data, bmih.biClrUsed * 4) )
04150 return GE_FALSE;
04151
04152 bPad -= bmih.biClrUsed * 4;
04153
04154 Bmp->Info.Format = GE_PIXELFORMAT_8BIT_PAL;
04155 pelBytes = 1;
04156 break;
04157 case 16:
04158 Bmp->Info.Format = GE_PIXELFORMAT_16BIT_555_RGB;
04159
04160 pelBytes = 2;
04161 break;
04162 case 24:
04163 Bmp->Info.Format = GE_PIXELFORMAT_24BIT_BGR;
04164 pelBytes = 3;
04165 break;
04166 case 32:
04167 Bmp->Info.Format = GE_PIXELFORMAT_32BIT_XRGB;
04168 pelBytes = 4;
04169 break;
04170 default:
04171 return GE_FALSE;
04172 }
04173
04174 if ( bPad < 0 )
04175 {
04176 geErrorLog_AddString(-1,"CreateFromFile : bPad bad", NULL);
04177 return GE_FALSE;
04178 }
04179
04180 geVFile_Seek(F, bPad, GE_VFILE_SEEKCUR);
04181
04182 Bmp->Info.Width = bmih.biWidth;
04183 Bmp->Info.Height = abs(bmih.biHeight);
04184 Bmp->Info.Stride = ((bmih.biWidth+3)&(~3));
04185
04186 Bmp->Info.HasColorKey = GE_FALSE;
04187
04188 myRowWidth = Bmp->Info.Stride * pelBytes;
04189 bmpRowWidth = (((bmih.biWidth * pelBytes) + 3)&(~3));
04190
04191 assert( bmpRowWidth <= myRowWidth );
04192
04193 if ( ! geBitmap_AllocSystemMip(Bmp,0) )
04194 return GE_FALSE;
04195
04196 if ( bmih.biHeight > 0 )
04197 {
04198 int y;
04199 char * row;
04200 row = Bmp->Data[0];
04201 row += (Bmp->Info.Height - 1) * myRowWidth;
04202 for(y= Bmp->Info.Height;y--;)
04203 {
04204 if ( ! geVFile_Read(F, row, bmpRowWidth) )
04205 return GE_FALSE;
04206 row -= myRowWidth;
04207 }
04208 }
04209 else
04210 {
04211 int y;
04212 char * row;
04213 row = Bmp->Data[0];
04214 for(y= Bmp->Info.Height;y--;)
04215 {
04216 if ( ! geVFile_Read(F, row, bmpRowWidth) )
04217 return GE_FALSE;
04218 row += myRowWidth;
04219 }
04220 }
04221
04222 return GE_TRUE;
04223 }
04224
04225
04226
04227 static geBoolean geBitmap_IsTGA(geVFile * F)
04228 {
04229 char targa[18];
04230 TGAHEADER tgah;
04231
04232 if (!geVFile_Seek(F, - 18, GE_VFILE_SEEKEND))
04233 return GE_FALSE;
04234
04235 if(!geVFile_Read(F, &targa, 18))
04236 return GE_FALSE;
04237 geVFile_Seek(F, 0, GE_VFILE_SEEKSET);
04238
04239
04240 if(!strcmp(targa, "TRUEVISION-XFILE."))
04241 return GE_TRUE;
04242
04243
04244 if(!geVFile_Read(F, &tgah, 18))
04245 return GE_FALSE;
04246 geVFile_Seek(F, 0, GE_VFILE_SEEKSET);
04247
04248 if(tgah.ColorMapType != 0 && tgah.ColorMapType != 1)
04249 return GE_FALSE;
04250 else if(tgah.ImageType != 1 && tgah.ImageType != 2 && tgah.ImageType != 9 && tgah.ImageType != 10)
04251 return GE_FALSE;
04252 else if(tgah.PixelDepth != 8 && tgah.PixelDepth != 16 && tgah.PixelDepth != 24 && tgah.PixelDepth != 32)
04253 return GE_FALSE;
04254 else
04255 return GE_TRUE;
04256
04257
04258 return GE_FALSE;
04259 }
04260
04261
04262
04263 static geBoolean geBitmap_ReadFromTGA(geBitmap * Bmp, geVFile * File)
04264 {
04265 TGAHEADER tgah;
04266 int alphabits;
04267 int fliphoriz;
04268 int flipvert;
04269 int myRowWidth,bmpRowWidth,pelBytes;
04270 long ImageOffset = 0;
04271 geBitmap *AlphaBmp = NULL;
04272
04273
04274
04275 if(!geVFile_Read(File, &tgah, 18))
04276 return GE_FALSE;
04277
04278 Bmp->Info.Width = tgah.Width;
04279 Bmp->Info.Height = tgah.Height;
04280 Bmp->Info.Stride = ((tgah.Width+3)&(~3));
04281 Bmp->Info.HasColorKey = GE_FALSE;
04282
04283 alphabits = tgah.ImageDescriptor & 0x0f;
04284 fliphoriz = (tgah.ImageDescriptor & 0x10) ? 0 : 1;
04285 flipvert = (tgah.ImageDescriptor & 0x20) ? 1 : 0;
04286
04287
04288
04289 switch (tgah.PixelDepth)
04290 {
04291 case 8 :
04292 pelBytes=1;
04293 Bmp->Info.Format = GE_PIXELFORMAT_8BIT_PAL;
04294 ImageOffset = 0;
04295
04296
04297 if(tgah.CMEntrySize == 16)
04298 {
04299 if ( ! (Bmp->Info.Palette = geBitmap_Palette_Create(GE_PIXELFORMAT_16BIT_555_RGB, tgah.CMLength)) )
04300 return GE_FALSE;
04301 }
04302 else if(tgah.CMEntrySize == 24)
04303 {
04304 if ( ! (Bmp->Info.Palette = geBitmap_Palette_Create(GE_PIXELFORMAT_24BIT_BGR, tgah.CMLength)) )
04305 return GE_FALSE;
04306 }
04307 else if(tgah.CMEntrySize == 32)
04308 {
04309 if ( ! (Bmp->Info.Palette = geBitmap_Palette_Create(GE_PIXELFORMAT_32BIT_XRGB, tgah.CMLength)) )
04310 return GE_FALSE;
04311 }
04312 else
04313 return GE_FALSE;
04314
04315
04316 geVFile_Seek(File, tgah.IDLength, GE_VFILE_SEEKCUR);
04317
04318 if ( ! geVFile_Read(File, Bmp->Info.Palette->Data, tgah.CMLength*(tgah.CMEntrySize/8)) )
04319 return GE_FALSE;
04320
04321 break;
04322
04323 case 16 :
04324 pelBytes = 2;
04325 Bmp->Info.Format = GE_PIXELFORMAT_16BIT_555_RGB;
04326 ImageOffset = tgah.IDLength+((tgah.CMEntrySize/8) * tgah.CMLength);
04327 break;
04328
04329 case 24 :
04330 pelBytes = 3;
04331 Bmp->Info.Format = GE_PIXELFORMAT_24BIT_BGR;
04332 ImageOffset = tgah.IDLength+((tgah.CMEntrySize/8) * tgah.CMLength);
04333 break;
04334
04335 case 32 :
04336
04337 AlphaBmp = geBitmap_Create_Base();
04338
04339 if (!AlphaBmp)
04340 return GE_FALSE;
04341
04342 AlphaBmp->Info.Width = tgah.Width;
04343 AlphaBmp->Info.Height = tgah.Height;
04344 AlphaBmp->Info.Stride = ((tgah.Width+3)&(~3));
04345 AlphaBmp->Info.HasColorKey = GE_FALSE;
04346 AlphaBmp->Info.Format = GE_PIXELFORMAT_8BIT_GRAY;
04347
04348 if ( ! geBitmap_AllocSystemMip(AlphaBmp,0) )
04349 goto fail;
04350
04351
04352 pelBytes = 3;
04353 Bmp->Info.Format = GE_PIXELFORMAT_24BIT_BGR;
04354
04355 ImageOffset = tgah.IDLength+((tgah.CMEntrySize/8) * tgah.CMLength);
04356
04357 break;
04358
04359 default :
04360 return GE_FALSE;
04361 }
04362
04363
04364
04365 if ( ! geBitmap_AllocSystemMip(Bmp,0) )
04366 goto fail;
04367
04368
04369 geVFile_Seek(File, ImageOffset, GE_VFILE_SEEKCUR);
04370
04371 myRowWidth = Bmp->Info.Stride * pelBytes;
04372 bmpRowWidth = (((tgah.Width * pelBytes) + 3)&(~3));
04373 assert( bmpRowWidth <= myRowWidth );
04374
04375
04376
04377
04378
04379
04380 if(tgah.ImageType == 1 || tgah.ImageType == 2)
04381 {
04382 int count, y;
04383 char *row;
04384 char * alpharow;
04385 row = Bmp->Data[0];
04386 alpharow = NULL;
04387
04388 if(tgah.PixelDepth == 32)
04389 alpharow = AlphaBmp->Data[0];
04390
04391 if(fliphoriz)
04392 {
04393 row += (Bmp->Info.Height - 1) * myRowWidth;
04394 if(tgah.PixelDepth == 32)
04395 alpharow += (AlphaBmp->Info.Height - 1) * (AlphaBmp->Info.Stride);
04396 }
04397
04398 for(y= Bmp->Info.Height;y--;)
04399 {
04400
04401 for(count=0; count<Bmp->Info.Stride; count++ )
04402 {
04403 geVFile_Read(File, row, pelBytes);
04404 row += pelBytes;
04405 if(tgah.PixelDepth == 32)
04406 {
04407 geVFile_Read(File, alpharow, 1);
04408 alpharow++;
04409 }
04410 }
04411 if(fliphoriz)
04412 {
04413
04414 row -= 2*myRowWidth;
04415 if(tgah.PixelDepth == 32)
04416 alpharow -= 2*(AlphaBmp->Info.Stride);
04417 }
04418 }
04419 }
04420
04421 else if(tgah.ImageType == 9 || tgah.ImageType == 10)
04422 {
04423 int i, j, k, y;
04424 char buff[4];
04425 char * row;
04426 char * alpharow;
04427 row = Bmp->Data[0];
04428 alpharow = NULL;
04429 y = 0;
04430 k = 1;
04431
04432 if(tgah.PixelDepth == 32)
04433 alpharow = AlphaBmp->Data[0];
04434
04435 if(fliphoriz)
04436 {
04437 row += (Bmp->Info.Height - 1) * myRowWidth;
04438 if(tgah.PixelDepth == 32)
04439 alpharow += (AlphaBmp->Info.Height - 1) * (AlphaBmp->Info.Stride);
04440 }
04441 while(y < Bmp->Info.Height)
04442 {
04443
04444
04445
04446
04447
04448 geVFile_Read(File, buff, 1);
04449
04450 j = buff[0] & 0x7f;
04451
04452 if(buff[0] & 0x80)
04453 {
04454 geVFile_Read(File, buff, pelBytes);
04455 if(tgah.PixelDepth == 32)
04456 geVFile_Read(File, &(buff[3]), 1);
04457
04458 for(i = 0; i <= j; i++)
04459 {
04460 *row++ = buff[0];
04461 if(pelBytes>1) *row++ = buff[1];
04462 if(pelBytes>2) *row++ = buff[2];
04463 if(tgah.PixelDepth == 32) *alpharow++ = buff[3];
04464 k++;
04465 if(k > Bmp->Info.Stride)
04466 {
04467 k=1;
04468 y++;
04469 if(fliphoriz)
04470 {
04471
04472 row -= 2*myRowWidth;
04473 if(tgah.PixelDepth == 32)
04474 alpharow -= 2*(AlphaBmp->Info.Stride);
04475 }
04476 }
04477 }
04478 }
04479 else
04480 {
04481 for(i = 0; i <= j; i++)
04482 {
04483 geVFile_Read(File, row, pelBytes);
04484 row += pelBytes;
04485 if(tgah.PixelDepth == 32)
04486 {
04487 geVFile_Read(File, alpharow, 1);
04488 alpharow++;
04489 }
04490 k++;
04491 if(k > Bmp->Info.Stride)
04492 {
04493 k=1;
04494 y++;
04495 if(fliphoriz)
04496 {
04497
04498 row -= 2*myRowWidth;
04499 if(tgah.PixelDepth == 32)
04500 alpharow -= 2*(AlphaBmp->Info.Stride);
04501 }
04502 }
04503 }
04504 }
04505 }
04506 }
04507 else
04508 goto fail;
04509
04510
04511 if(tgah.PixelDepth == 32)
04512 {
04513 assert(AlphaBmp);
04514 if(!geBitmap_SetAlpha( Bmp, AlphaBmp))
04515 goto fail;
04516 geBitmap_Destroy(&AlphaBmp);
04517 geBitmap_SetPreferredFormat(Bmp,GE_PIXELFORMAT_32BIT_ARGB);
04518 }
04519
04520 return GE_TRUE;
04521
04522 fail:
04523 if(AlphaBmp);
04524 geBitmap_Destroy(&AlphaBmp);
04525 return GE_FALSE;
04526 }
04527
04528
04529
04530
04531 #define INFO_FLAG_WH_ARE_LOG2 (1<<0)
04532 #define INFO_FLAG_HAS_CK (1<<1)
04533 #define INFO_FLAG_HAS_ALPHA (1<<2)
04534 #define INFO_FLAG_HAS_PAL (1<<3)
04535
04536 #define INFO_FLAG_IF_NOT_LOG2_ARE_BYTE (1<<5)
04537
04538 geBoolean geBitmap_ReadInfo(geBitmap *Bmp,geVFile * F)
04539 {
04540 uint8 data[4];
04541 uint8 flags;
04542 uint8 b;
04543 uint16 w;
04544 geBitmap_Info * pi;
04545
04546 pi = &(Bmp->Info);
04547
04548 if ( ! geVFile_Read(F,data,3) )
04549 return GE_FALSE;
04550
04551 flags = data[0];
04552
04553 pi->Format = data[1];
04554
04555 b = data[2];
04556
04557 pi->MaximumMip = (b>>4)&0xF;
04558 Bmp->SeekMipCount = (b)&0xF;
04559
04560 if ( flags & INFO_FLAG_HAS_PAL )
04561 pi->Palette = (geBitmap_Palette *)1;
04562 if ( flags & INFO_FLAG_HAS_ALPHA )
04563 Bmp->Alpha = (geBitmap *)1;
04564
04565 if ( flags & INFO_FLAG_WH_ARE_LOG2 )
04566 {
04567 int logw,logh;
04568
04569 if ( ! geVFile_Read(F,&b,1) )
04570 return GE_FALSE;
04571
04572 logw = (b>>4)&0xF;
04573 logh = (b )&0xF;
04574
04575 pi->Width = 1<<logw;
04576 pi->Height= 1<<logh;
04577 }
04578 else if ( flags & INFO_FLAG_IF_NOT_LOG2_ARE_BYTE )
04579 {
04580 if ( ! geVFile_Read(F,&b,1) )
04581 return GE_FALSE;
04582 pi->Width = b;
04583 if ( ! geVFile_Read(F,&b,1) )
04584 return GE_FALSE;
04585 pi->Height = b;
04586 }
04587 else
04588 {
04589 if ( ! geVFile_Read(F,&w,2) )
04590 return GE_FALSE;
04591 pi->Width = w;
04592 if ( ! geVFile_Read(F,&w,2) )
04593 return GE_FALSE;
04594 pi->Height = w;
04595 }
04596
04597 if ( (flags & INFO_FLAG_HAS_CK) && gePixelFormat_BytesPerPel(pi->Format) > 0 )
04598 {
04599 uint8 * ptr;
04600 pi->HasColorKey = GE_TRUE;
04601
04602 if ( ! geVFile_Read(F,data,gePixelFormat_BytesPerPel(pi->Format)) )
04603 return GE_FALSE;
04604
04605 ptr = data;
04606 pi->ColorKey = gePixelFormat_GetPixel(pi->Format,&ptr);
04607 }
04608
04609 pi->Stride = pi->Width;
04610
04611 return GE_TRUE;
04612 }
04613
04614 geBoolean geBitmap_WriteInfo(const geBitmap *Bmp,geVFile * F)
04615 {
04616 uint8 data[64];
04617 uint8 * ptr;
04618 uint8 flags;
04619 uint8 b;
04620 int len,logw,logh;
04621 const geBitmap_Info * pi;
04622
04623
04624
04625
04626
04627
04628
04629
04630
04631
04632
04633
04634
04635
04636
04637
04638
04639 pi = &(Bmp->Info);
04640 flags = 0;
04641 ptr = data + 1;
04642
04643 assert( pi->Width < 65536 && pi->Height < 65536 );
04644 assert( pi->MinimumMip == 0 );
04645 assert( gePixelFormat_IsValid(pi->Format) );
04646
04647 *ptr++ = pi->Format;
04648
04649 b = (pi->MaximumMip << 4) + Bmp->SeekMipCount;
04650 *ptr++ = b;
04651
04652 if ( pi->Palette )
04653 flags |= INFO_FLAG_HAS_PAL;
04654 if ( Bmp->Alpha )
04655 flags |= INFO_FLAG_HAS_ALPHA;
04656
04657 for(logw=0;(1<<logw) < pi->Width;logw++);
04658 for(logh=0;(1<<logh) < pi->Height;logh++);
04659
04660 if ( (1<<logw) == pi->Width && (1<<logh) == pi->Height )
04661 {
04662 flags |= INFO_FLAG_WH_ARE_LOG2;
04663 assert( logw <= 0xF && logh <= 0xF );
04664 b = (logw<<4) + logh;
04665 *ptr++ = b;
04666 }
04667 else
04668 {
04669 if ( pi->Width < 256 && pi->Height < 256 )
04670 {
04671 flags |= INFO_FLAG_IF_NOT_LOG2_ARE_BYTE;
04672 *ptr++ = pi->Width;
04673 *ptr++ = pi->Height;
04674 }
04675 else
04676 {
04677 *((uint16 *)ptr) = pi->Width; ptr += 2;
04678 *((uint16 *)ptr) = pi->Height; ptr += 2;
04679 }
04680 }
04681
04682 if ( pi->HasColorKey && gePixelFormat_BytesPerPel(pi->Format) > 0 )
04683 {
04684 flags |= INFO_FLAG_HAS_CK;
04685
04686 gePixelFormat_PutPixel(pi->Format,&ptr,pi->ColorKey);
04687 }
04688
04689 *data = flags;
04690 len = (int)(ptr - data);
04691
04692 if ( ! geVFile_Write(F,data,len) )
04693 return GE_FALSE;
04694
04695 return GE_TRUE;
04696 }
04697
04698
04699
04700 geBoolean geBitmap_Palette_BlitData(gePixelFormat SrcFormat,const void *SrcData,const geBitmap_Palette * SrcPal,
04701 gePixelFormat DstFormat, void *DstData,const geBitmap_Palette * DstPal,
04702 int Pixels)
04703 {
04704 char *SrcPtr,*DstPtr;
04705 geBoolean SrcHasCK,DstHasCK;
04706 uint32 SrcCK=0,DstCK=0;
04707 int SrcCKi=0,DstCKi=0;
04708
04709 assert( SrcData && DstData );
04710
04711 assert( gePixelFormat_IsRaw(SrcFormat) );
04712 assert( gePixelFormat_IsRaw(DstFormat) );
04713
04714 SrcPtr = (char *)SrcData;
04715 DstPtr = (char *)DstData;
04716
04717 if ( SrcPal && SrcPal->HasColorKey )
04718 {
04719 SrcHasCK = GE_TRUE;
04720 SrcCK = SrcPal->ColorKey;
04721 SrcCKi = SrcPal->ColorKeyIndex;
04722 }
04723 else
04724 {
04725 SrcHasCK = GE_FALSE;
04726 }
04727
04728 if ( DstPal && DstPal->HasColorKey )
04729 {
04730 DstHasCK = GE_TRUE;
04731 DstCK = DstPal->ColorKey;
04732 DstCKi = DstPal->ColorKeyIndex;
04733 }
04734 else
04735 {
04736 DstHasCK = GE_FALSE;
04737 }
04738
04739 #if 0 // {} ?
04740 if ( SrcHasCK && DstHasCK )
04741 {
04742 if ( DstCKi == -1 )
04743 DstCKi = SrcCKi;
04744 }
04745 #endif
04746
04747
04748
04749
04750
04751
04752
04753
04754
04755 {
04756 uint32 Pixel;
04757 int p,R,G,B,A;
04758 const gePixelFormat_Operations *SrcOps,*DstOps;
04759 gePixelFormat_Composer ComposePixel;
04760 gePixelFormat_Decomposer DecomposePixel;
04761 gePixelFormat_PixelPutter PutPixel;
04762 gePixelFormat_PixelGetter GetPixel;
04763
04764 SrcOps = gePixelFormat_GetOperations(SrcFormat);
04765 DstOps = gePixelFormat_GetOperations(DstFormat);
04766 assert(SrcOps && DstOps);
04767
04768 GetPixel = SrcOps->GetPixel;
04769 DecomposePixel = SrcOps->DecomposePixel;
04770 ComposePixel = DstOps->ComposePixel;
04771 PutPixel = DstOps->PutPixel;
04772
04773 if ( SrcOps->AMask && ! DstOps->AMask )
04774 {
04775
04776 for(p=0;p<Pixels;p++)
04777 {
04778 Pixel = GetPixel(&SrcPtr);
04779 DecomposePixel(Pixel,&R,&G,&B,&A);
04780 if ( SrcHasCK && ( p == SrcCKi || Pixel == SrcCK ) )
04781 A = 0;
04782 Pixel = ComposePixel(R,G,B,A);
04783
04784 if ( DstHasCK )
04785 {
04786 if ( p == DstCKi || A < 128 )
04787 Pixel = DstCK;
04788 else if ( Pixel == DstCK )
04789 Pixel ^= 1;
04790
04791
04792 }
04793 PutPixel(&DstPtr,Pixel);
04794 }
04795 }
04796 else if ( ! SrcOps->AMask && DstOps->AMask )
04797 {
04798
04799 for(p=0;p<Pixels;p++)
04800 {
04801 Pixel = GetPixel(&SrcPtr);
04802 DecomposePixel(Pixel,&R,&G,&B,&A);
04803 if ( SrcHasCK && ( p == SrcCKi || Pixel == SrcCK ) )
04804 A = 0;
04805
04806 Pixel = ComposePixel(R,G,B,A);
04807 if ( DstHasCK )
04808 {
04809 if ( p == DstCKi )
04810 Pixel = DstCK;
04811 else if ( Pixel == DstCK )
04812 Pixel ^= 1;
04813 }
04814 PutPixel(&DstPtr,Pixel);
04815 }
04816 }
04817 else
04818 {
04819
04820 for(p=0;p<Pixels;p++)
04821 {
04822 Pixel = GetPixel(&SrcPtr);
04823 DecomposePixel(Pixel,&R,&G,&B,&A);
04824 if ( (SrcHasCK && ( p == SrcCKi || Pixel == SrcCK )) ||
04825 DstHasCK && p == DstCKi )
04826 {
04827 Pixel = DstCK;
04828 }
04829 else
04830 {
04831 Pixel = ComposePixel(R,G,B,A);
04832 if ( DstHasCK && Pixel == DstCK )
04833 Pixel ^= 1;
04834 }
04835 PutPixel(&DstPtr,Pixel);
04836 }
04837 }
04838 }
04839
04840 return GE_TRUE;
04841 }
04842
04843 GENESISAPI geBitmap_Palette * GENESISCC geBitmap_Palette_Create(gePixelFormat Format,int Size)
04844 {
04845 geBitmap_Palette * P;
04846 int DataBytes;
04847 const gePixelFormat_Operations * ops;
04848
04849 ops = gePixelFormat_GetOperations(Format);
04850 if ( ! ops->RMask )
04851 {
04852 geErrorLog_AddString(-1,"geBitmap_Palette_Create : Invalid format for a palette!", NULL);
04853 return NULL;
04854 }
04855
04856 DataBytes = gePixelFormat_BytesPerPel(Format) * Size;
04857 if ( DataBytes == 0 )
04858 {
04859 geErrorLog_AddString(-1,"geBitmap_Palette_Create : Invalid format for a palette!", NULL);
04860 return NULL;
04861 }
04862
04863 allocate(P);
04864 if ( ! P ) return NULL;
04865 clear(P);
04866
04867 P->Size = Size;
04868 P->Format = Format;
04869 if ( ! (P->Data = geRam_Allocate(DataBytes)) )
04870 {
04871 geRam_Free(P);
04872 return NULL;
04873 }
04874
04875 P->RefCount = 1;
04876 P->LockCount = 0;
04877
04878 P->HasColorKey = GE_FALSE;
04879
04880 return P;
04881 }
04882
04883 GENESISAPI geBoolean GENESISCC geBitmap_Palette_CreateRef(geBitmap_Palette *P)
04884 {
04885 if ( ! P || P->RefCount < 1 )
04886 return GE_FALSE;
04887 P->RefCount ++;
04888 return GE_TRUE;
04889 }
04890
04891 GENESISAPI geBitmap_Palette * GENESISCC geBitmap_Palette_CreateFromBitmap(geBitmap * Bmp,geBoolean Slow)
04892 {
04893 geBitmap_Palette * Pal;
04894 Pal = geBitmap_GetPalette(Bmp);
04895 if ( Pal )
04896 {
04897 geBitmap_Palette_CreateRef(Pal);
04898 return Pal;
04899 }
04900 else
04901 {
04902 return createPaletteFromBitmap(Bmp, Slow);
04903 }
04904 }
04905
04906 geBitmap_Palette * BITMAP_GENESIS_INTERNAL geBitmap_Palette_CreateFromDriver(DRV_Driver * Driver,gePixelFormat Format,int Size)
04907 {
04908 geBitmap_Palette * P;
04909 geRDriver_THandleInfo TInfo;
04910
04911 assert(Driver);
04912
04913 allocate(P);
04914 if ( ! P ) return NULL;
04915 clear(P);
04916
04917 P->Size = Size;
04918 P->Driver = Driver;
04919
04920
04921
04922
04923 assert( gePixelFormat_IsRaw(Format) );
04924
04925 P->DriverHandle = geBitmap_CreateTHandle(Driver,Size,1,1,
04926 Format,0,0,gePixelFormat_HasAlpha(Format),0,RDRIVER_PF_PALETTE);
04927 if ( ! P->DriverHandle )
04928 {
04929 geErrorLog_AddString(-1,"Palette_CreateFromDriver : CreateTHandle", NULL);
04930 geRam_Free(P);
04931 return NULL;
04932 }
04933
04934 Driver->THandle_GetInfo(P->DriverHandle,0,&TInfo);
04935 P->Format = TInfo.PixelFormat.PixelFormat;
04936
04937 P->HasColorKey = (TInfo.Flags & RDRIVER_THANDLE_HAS_COLORKEY) ? GE_TRUE : GE_FALSE;
04938 P->ColorKey = TInfo.ColorKey;
04939 P->ColorKeyIndex = -1;
04940
04941 P->RefCount = 1;
04942
04943 return P;
04944 }
04945
04946 GENESISAPI geBitmap_Palette * GENESISCC geBitmap_Palette_CreateCopy(const geBitmap_Palette *Palette)
04947 {
04948 geBitmap_Palette * P;
04949
04950 if ( ! Palette )
04951 return NULL;
04952
04953 if ( Palette->Driver )
04954 {
04955 P = geBitmap_Palette_CreateFromDriver(Palette->Driver,Palette->Format,Palette->Size);
04956 }
04957 else
04958 {
04959 P = geBitmap_Palette_Create(Palette->Format,Palette->Size);
04960 }
04961
04962 if ( ! P ) return NULL;
04963
04964 if ( ! geBitmap_Palette_Copy(Palette,P) )
04965 {
04966 geBitmap_Palette_Destroy(&P);
04967 return NULL;
04968 }
04969
04970 return P;
04971 }
04972
04973 GENESISAPI geBoolean GENESISCC geBitmap_Palette_Destroy(geBitmap_Palette ** ppPalette)
04974 {
04975 geBitmap_Palette * Palette;
04976 assert(ppPalette);
04977 if ( Palette = *ppPalette )
04978 {
04979 if ( Palette->LockCount )
04980 return GE_FALSE;
04981 Palette->RefCount --;
04982 if ( Palette->RefCount <= 0 )
04983 {
04984 if ( Palette->Data )
04985 geRam_Free(Palette->Data);
04986 if ( Palette->DriverHandle )
04987 {
04988 Palette->Driver->THandle_Destroy(Palette->DriverHandle);
04989 Palette->DriverHandle = NULL;
04990 }
04991 geRam_Free(Palette);
04992 }
04993 }
04994 *ppPalette = NULL;
04995 return GE_TRUE;
04996 }
04997
04998 GENESISAPI geBoolean GENESISCC geBitmap_Palette_Lock(geBitmap_Palette *P, void **pBits, gePixelFormat *pFormat,int *pSize)
04999 {
05000 assert(P);
05001 assert(pBits);
05002
05003 if ( P->LockCount )
05004 return GE_FALSE;
05005 P->LockCount++;
05006
05007 *pBits = NULL;
05008
05009 if ( P->Data )
05010 {
05011 *pBits = P->Data;
05012 if ( pFormat )
05013 *pFormat= P->Format;
05014 if ( pSize )
05015 *pSize = P->Size;
05016 }
05017 else if ( P->DriverHandle )
05018 {
05019 geRDriver_THandleInfo TInfo;
05020
05021 if ( ! P->Driver->THandle_GetInfo(P->DriverHandle,0,&TInfo) )
05022 return GE_FALSE;
05023
05024 if ( TInfo.Height != 1 )
05025 return GE_FALSE;
05026
05027 if ( ! (P->Driver->THandle_Lock(P->DriverHandle,0,pBits)) )
05028 *pBits = NULL;
05029
05030 P->DriverBits = *pBits;
05031
05032 if ( pFormat )
05033 *pFormat = TInfo.PixelFormat.PixelFormat;
05034 if ( pSize )
05035 *pSize = TInfo.Width;
05036 }
05037
05038 return (*pBits) ? GE_TRUE : GE_FALSE;
05039 }
05040
05041 GENESISAPI geBoolean GENESISCC geBitmap_Palette_UnLock(geBitmap_Palette *P)
05042 {
05043 assert(P);
05044 if ( P->LockCount <= 0 )
05045 return GE_FALSE;
05046 P->LockCount--;
05047 if ( P->LockCount == 0 )
05048 {
05049 if ( P->HasColorKey )
05050 {
05051 if ( P->ColorKeyIndex >= 0 && P->ColorKeyIndex < P->Size )
05052 {
05053 uint8 *Bits=NULL,*pBits=NULL;
05054 uint32 Pixel;
05055 int p;
05056 const gePixelFormat_Operations *ops;
05057 gePixelFormat_PixelPutter PutPixel;
05058 gePixelFormat_PixelGetter GetPixel;
05059
05060 if ( P->Data )
05061 {
05062 Bits = P->Data;
05063 }
05064 else if ( P->DriverBits )
05065 {
05066 Bits = P->DriverBits;
05067 }
05068
05069 ops = gePixelFormat_GetOperations(P->Format);
05070 assert(ops);
05071
05072 GetPixel = ops->GetPixel;
05073 PutPixel = ops->PutPixel;
05074
05075 for(p=0;p<P->Size;p++)
05076 {
05077 pBits = Bits;
05078 Pixel = GetPixel(&Bits);
05079 if ( p == P->ColorKeyIndex )
05080 {
05081 PutPixel(&pBits,P->ColorKey);
05082 }
05083 else if ( Pixel == P->ColorKey )
05084 {
05085 Pixel ^= 1;
05086 PutPixel(&pBits,Pixel);
05087 }
05088 }
05089 }
05090 }
05091 if ( P->DriverHandle )
05092 {
05093 if ( ! P->Driver->THandle_UnLock(P->DriverHandle,0) )
05094 return GE_FALSE;
05095 P->DriverBits = NULL;
05096 }
05097 }
05098 return GE_TRUE;
05099 }
05100
05101 GENESISAPI geBoolean GENESISCC geBitmap_Palette_SetFormat(geBitmap_Palette * P,gePixelFormat Format)
05102 {
05103 void * NewData;
05104
05105 assert(P);
05106
05107 if ( P->DriverHandle )
05108 return GE_FALSE;
05109
05110 assert( ! P->HasColorKey );
05111
05112 if ( Format == P->Format )
05113 return GE_TRUE;
05114
05115 NewData = geRam_Allocate( gePixelFormat_BytesPerPel(Format) * P->Size );
05116 if ( ! NewData )
05117 return GE_FALSE;
05118
05119 if ( ! geBitmap_Palette_BlitData(P->Format,P->Data,NULL,Format,NewData,NULL,P->Size) )
05120 {
05121 geRam_Free(NewData);
05122 return GE_FALSE;
05123 }
05124
05125 geRam_Free(P->Data);
05126 P->Data = NewData;
05127 P->Format = Format;
05128
05129 return GE_TRUE;
05130 }
05131
05132 GENESISAPI geBoolean GENESISCC geBitmap_Palette_GetData(const geBitmap_Palette *P,void *Into,gePixelFormat Format,int Size)
05133 {
05134 gePixelFormat FmFormat;
05135 const void *FmData;
05136 int FmSize;
05137 geBoolean Ret;
05138
05139 assert(P);
05140 assert(Into);
05141
05142 if ( ! geBitmap_Palette_Lock((geBitmap_Palette *)P,(void **)&FmData,&FmFormat,&FmSize) )
05143 return GE_FALSE;
05144
05145 if ( FmSize < Size )
05146 Size = FmSize;
05147
05148 Ret = geBitmap_Palette_BlitData(FmFormat,FmData,P,Format,Into,NULL,Size);
05149
05150 geBitmap_Palette_UnLock((geBitmap_Palette *)P);
05151
05152 return Ret;
05153 }
05154
05155 GENESISAPI geBoolean GENESISCC geBitmap_Palette_GetInfo(const geBitmap_Palette *P,geBitmap_Info *pInfo)
05156 {
05157 assert(P && pInfo);
05158
05159 pInfo->Width = pInfo->Stride = P->Size;
05160 pInfo->Height = 1;
05161
05162 pInfo->Format = P->Format;
05163 pInfo->HasColorKey = P->HasColorKey;
05164 pInfo->ColorKey = P->ColorKey;
05165 pInfo->MaximumMip = pInfo->MinimumMip = 0;
05166 pInfo->Palette = NULL;
05167
05168 return GE_TRUE;
05169 }
05170
05171 GENESISAPI geBoolean GENESISCC geBitmap_Palette_SetData(geBitmap_Palette *P,const void *From,gePixelFormat Format,int Colors)
05172 {
05173 gePixelFormat PalFormat;
05174 void *PalData;
05175 int PalSize;
05176 geBoolean Ret;
05177
05178 assert(P);
05179 assert(From);
05180
05181 if ( ! geBitmap_Palette_Lock(P,&PalData,&PalFormat,&PalSize) )
05182 return GE_FALSE;
05183
05184 if ( PalSize < Colors )
05185 Colors = PalSize;
05186
05187 Ret = geBitmap_Palette_BlitData(Format,From,NULL,PalFormat,PalData,P,Colors);
05188
05189 if ( ! geBitmap_Palette_UnLock(P) )
05190 return GE_FALSE;
05191
05192 return Ret;
05193 }
05194
05195 GENESISAPI geBoolean GENESISCC geBitmap_Palette_Copy(const geBitmap_Palette * Fm,geBitmap_Palette * To)
05196 {
05197 gePixelFormat FmFormat,ToFormat;
05198 void *FmData,*ToData;
05199 int FmSize,ToSize;
05200 geBoolean Ret;
05201
05202 assert(Fm);
05203 assert(To);
05204 if ( Fm == To )
05205 return GE_TRUE;
05206
05207 if ( ! geBitmap_Palette_Lock((geBitmap_Palette *)Fm,&FmData,&FmFormat,&FmSize) )
05208 return GE_FALSE;
05209
05210 if ( ! geBitmap_Palette_Lock(To,&ToData,&ToFormat,&ToSize) )
05211 {
05212 geBitmap_Palette_UnLock((geBitmap_Palette *)Fm);
05213 return GE_FALSE;
05214 }
05215
05216 if ( FmSize > ToSize )
05217 {
05218 Ret = GE_FALSE;
05219 }
05220 else
05221 {
05222 Ret = geBitmap_Palette_BlitData(FmFormat,FmData,Fm,ToFormat,ToData,To,FmSize);
05223 }
05224
05225 geBitmap_Palette_UnLock((geBitmap_Palette *)Fm);
05226 geBitmap_Palette_UnLock(To);
05227
05228 return Ret;
05229 }
05230
05231 GENESISAPI geBoolean GENESISCC geBitmap_Palette_SetEntryColor(geBitmap_Palette *P,int Color,int R,int G,int B,int A)
05232 {
05233 assert(P);
05234
05235 if ( A < 80 && ! gePixelFormat_HasAlpha(P->Format) && P->HasColorKey )
05236 {
05237 return geBitmap_Palette_SetEntry(P,Color,P->ColorKey);
05238 }
05239 else if ( P->HasColorKey )
05240 {
05241 uint32 Pixel;
05242
05243
05244
05245 if ( Color == P->ColorKeyIndex )
05246 return GE_FALSE;
05247
05248 Pixel = gePixelFormat_ComposePixel(P->Format,R,G,B,A);
05249 if ( Pixel == P->ColorKey )
05250 Pixel ^= 1;
05251
05252 return geBitmap_Palette_SetEntry(P,Color,Pixel);
05253 }
05254 else
05255 {
05256 return geBitmap_Palette_SetEntry(P,Color,gePixelFormat_ComposePixel(P->Format,R,G,B,A));
05257 }
05258 }
05259
05260 GENESISAPI geBoolean GENESISCC geBitmap_Palette_GetEntryColor(const geBitmap_Palette *P,int Color,int *R,int *G,int *B,int *A)
05261 {
05262 uint32 Pixel;
05263 assert(P);
05264 if ( P->HasColorKey )
05265 {
05266 if ( Color == P->ColorKeyIndex )
05267 {
05268 *R = *G = *B = *A = 0;
05269 return GE_TRUE;
05270 }
05271 else
05272 {
05273 if ( ! geBitmap_Palette_GetEntry(P,Color,&Pixel) )
05274 return GE_FALSE;
05275 if ( Pixel == P->ColorKey )
05276 {
05277 *R = *G = *B = *A = 0;
05278 }
05279 else
05280 {
05281 gePixelFormat_DecomposePixel(P->Format,Pixel,R,G,B,A);
05282 }
05283 }
05284 }
05285 else
05286 {
05287 if ( ! geBitmap_Palette_GetEntry(P,Color,&Pixel) )
05288 return GE_FALSE;
05289 gePixelFormat_DecomposePixel(P->Format,Pixel,R,G,B,A);
05290 }
05291 return GE_TRUE;
05292 }
05293
05294 GENESISAPI geBoolean GENESISCC geBitmap_Palette_SetEntry(geBitmap_Palette *P,int Color,uint32 Pixel)
05295 {
05296 assert(P);
05297
05298 if ( P->HasColorKey )
05299 {
05300 if ( Color == P->ColorKeyIndex )
05301 return GE_TRUE;
05302 }
05303
05304 if ( P->Data )
05305 {
05306 char *Data;
05307
05308 if ( Color >= P->Size )
05309 return GE_FALSE;
05310
05311 Data = (char *)(P->Data) + Color * gePixelFormat_BytesPerPel(P->Format);
05312 gePixelFormat_PutPixel(P->Format,&Data,Pixel);
05313 }
05314 else
05315 {
05316 char *Data;
05317 gePixelFormat Format;
05318 int Size;
05319
05320 if ( ! geBitmap_Palette_Lock(P,&Data,&Format,&Size) )
05321 return GE_FALSE;
05322
05323 if ( Color >= Size )
05324 {
05325 geBitmap_Palette_UnLock(P);
05326 return GE_FALSE;
05327 }
05328
05329 Data += Color * gePixelFormat_BytesPerPel(Format);
05330 gePixelFormat_PutPixel(Format,&Data,Pixel);
05331
05332 geBitmap_Palette_UnLock(P);
05333 }
05334 return GE_TRUE;
05335 }
05336
05337 GENESISAPI geBoolean GENESISCC geBitmap_Palette_GetEntry(const geBitmap_Palette *P,int Color,uint32 *Pixel)
05338 {
05339
05340 assert(P);
05341
05342 if ( P->Data )
05343 {
05344 char *Data;
05345
05346 if ( Color >= P->Size )
05347 return GE_FALSE;
05348
05349 Data = (char *)(P->Data) + Color * gePixelFormat_BytesPerPel(P->Format);
05350 *Pixel = gePixelFormat_GetPixel(P->Format,&Data);
05351 }
05352 else
05353 {
05354 char *Data;
05355 gePixelFormat Format;
05356 int Size;
05357
05358
05359
05360 if ( ! geBitmap_Palette_Lock((geBitmap_Palette *)P,&Data,&Format,&Size) )
05361 return GE_FALSE;
05362
05363 if ( Color >= Size )
05364 {
05365 geBitmap_Palette_UnLock((geBitmap_Palette *)P);
05366 return GE_FALSE;
05367 }
05368
05369 Data += Color * gePixelFormat_BytesPerPel(Format);
05370 *Pixel = gePixelFormat_GetPixel(Format,&Data);
05371
05372 geBitmap_Palette_UnLock((geBitmap_Palette *)P);
05373 }
05374 return GE_TRUE;
05375 }
05376
05377 #define PALETTE_INFO_FORMAT_MASK (0x1F)
05378 #define PALETTE_INFO_FLAG_SIZE256 (1<<5) // 5 is the low
05379 #define PALETTE_INFO_FLAG_COMPRESS (1<<6)
05380
05381 GENESISAPI geBitmap_Palette * GENESISCC geBitmap_Palette_CreateFromFile(geVFile *F)
05382 {
05383 geBitmap_Palette * P;
05384 int Size;
05385 gePixelFormat Format;
05386 uint8 flags,b;
05387
05388 if ( ! geVFile_Read(F, &flags, sizeof(flags)) )
05389 return NULL;
05390
05391 Format = flags & PALETTE_INFO_FORMAT_MASK;
05392
05393 if ( flags & PALETTE_INFO_FLAG_SIZE256 )
05394 {
05395 Size = 256;
05396 }
05397 else
05398 {
05399 if ( ! geVFile_Read(F, &b, sizeof(b)) )
05400 return NULL;
05401 Size = b;
05402 }
05403
05404 P = geBitmap_Palette_Create(Format,Size);
05405 if ( ! P )
05406 return NULL;
05407
05408 if ( flags & PALETTE_INFO_FLAG_COMPRESS )
05409 {
05410 geErrorLog_AddString(-1,"Bitmap_Palette_CreateFromFile : codePal failed!",NULL);
05411 return GE_FALSE;
05412 }
05413 else
05414 {
05415 if ( ! geVFile_Read(F, P->Data, gePixelFormat_BytesPerPel(P->Format) * P->Size) )
05416 {
05417 geRam_Free(P);
05418 return NULL;
05419 }
05420 }
05421
05422 return P;
05423 }
05424
05425 GENESISAPI geBoolean GENESISCC geBitmap_Palette_WriteToFile(const geBitmap_Palette *P,geVFile *F)
05426 {
05427 int Size;
05428 gePixelFormat Format;
05429 void *Data;
05430
05431 assert(P);
05432
05433 assert( P->HasColorKey == GE_FALSE );
05434
05435
05436
05437 if ( ! geBitmap_Palette_Lock((geBitmap_Palette *)P,&Data,&Format,&Size) )
05438 return GE_FALSE;
05439
05440 {
05441 uint8 b;
05442
05443 b = Format;
05444 assert( b < 32 );
05445 if ( Size == 256 )
05446 b |= PALETTE_INFO_FLAG_SIZE256;
05447
05448 if ( ! geVFile_Write(F, &b, sizeof(b)) )
05449 {
05450 geBitmap_Palette_UnLock((geBitmap_Palette *)P);
05451 return GE_FALSE;
05452 }
05453
05454 if ( Size != 256 )
05455 {
05456 assert(Size < 256);
05457 b = Size;
05458
05459 if ( ! geVFile_Write(F, &b, sizeof(b)) )
05460 {
05461 geBitmap_Palette_UnLock((geBitmap_Palette *)P);
05462 return GE_FALSE;
05463 }
05464 }
05465 }
05466
05467 if ( ! geVFile_Write(F, Data, gePixelFormat_BytesPerPel(Format) * Size) )
05468 {
05469 geBitmap_Palette_UnLock((geBitmap_Palette *)P);
05470 return GE_FALSE;
05471 }
05472
05473 geBitmap_Palette_UnLock((geBitmap_Palette *)P);
05474
05475 return GE_TRUE;
05476 }
05477
05478
05479
05480
05481
05482 geBoolean geBitmap_IsValid(const geBitmap *Bmp)
05483 {
05484 if ( ! Bmp ) return GE_FALSE;
05485
05486 assert( Bmp->RefCount >= 1 );
05487
05488 assert( ! (Bmp->LockCount && Bmp->LockOwner) );
05489
05490 assert( !( (Bmp->DriverDataChanged || Bmp->DriverBitsLocked) &&
05491 ! Bmp->DriverHandle ) );
05492 assert( ! (Bmp->DriverHandle && ! Bmp->Driver) );
05493
05494 if ( ! geBitmap_Info_IsValid(&(Bmp->Info)) )
05495 return GE_FALSE;
05496
05497 if ( Bmp->DriverHandle && ! geBitmap_Info_IsValid(&(Bmp->DriverInfo)) )
05498 return GE_FALSE;
05499
05500 if ( Bmp->LockOwner && Bmp->Alpha )
05501 assert( Bmp->Alpha->LockOwner );
05502
05503 if ( Bmp->LockOwner )
05504 {
05505 assert(Bmp->LockOwner != Bmp);
05506 assert( Bmp->LockOwner->LockCount );
05507 }
05508
05509 if ( Bmp->DataOwner )
05510 {
05511 assert(Bmp->DataOwner != Bmp);
05512 assert( Bmp->DataOwner->RefCount >= 2 );
05513 }
05514
05515 if ( Bmp->Alpha )
05516 {
05517 assert(Bmp->Alpha != Bmp);
05518 if ( ! geBitmap_IsValid(Bmp->Alpha) )
05519 return GE_FALSE;
05520 }
05521
05522 return GE_TRUE;
05523 }
05524
05525 geBoolean geBitmap_Info_IsValid(const geBitmap_Info *Info)
05526 {
05527 if ( ! Info ) return GE_FALSE;
05528
05529 assert( Info->Width > 0 && Info->Height > 0 && Info->Stride >= Info->Width );
05530
05531 assert( Info->MinimumMip >= 0 && Info->MaximumMip < MAXMIPLEVELS && Info->MinimumMip <= Info->MaximumMip );
05532
05533 assert( Info->Format > GE_PIXELFORMAT_NO_DATA && Info->Format < GE_PIXELFORMAT_COUNT );
05534
05535
05536
05537
05538
05539 if ( Info->Palette )
05540 if ( ! geBitmap_Palette_IsValid(Info->Palette) )
05541 return GE_FALSE;
05542
05543 return GE_TRUE;
05544 }
05545
05546 geBoolean geBitmap_Palette_IsValid(const geBitmap_Palette *Pal)
05547 {
05548 if ( ! Pal ) return GE_FALSE;
05549
05550 assert( Pal->Data || Pal->DriverHandle );
05551 assert( !Pal->Data || !Pal->DriverHandle );
05552
05553 assert( (Pal->Driver && Pal->DriverHandle) ||
05554 (! Pal->Driver && ! Pal->DriverHandle) );
05555
05556 assert( Pal->RefCount >= 1 && Pal->Size >= 1 );
05557 assert( Pal->Format > GE_PIXELFORMAT_NO_DATA && Pal->Format < GE_PIXELFORMAT_COUNT );
05558
05559 return GE_TRUE;
05560 }
05561
05562 #ifdef _DEBUG
05563 GENESISAPI uint32 GENESISCC geBitmap_Debug_GetCount(void)
05564 {
05565
05566 return _Bitmap_Debug_ActiveCount;
05567 }
05568 GENESISAPI uint32 GENESISCC geBitmap_Debug_GetRefs(void)
05569 {
05570
05571 return _Bitmap_Debug_ActiveRefs;
05572 }
05573 #endif
05574
05575
05576
05577 GENESISAPI geBoolean GENESISCC geBitmap_GetAverageColor(const geBitmap *Bmp,int *pR,int *pG,int *pB)
05578 {
05579 {
05580 int bpp,x,y,w,h,xtra,dock;
05581 gePixelFormat Format;
05582 uint8 * ptr;
05583 uint32 R,G,B,A,Rt,Gt,Bt,cnt,ck;
05584
05585
05586
05587 if ( Bmp->DriverHandle && Bmp->DriverDataChanged )
05588 {
05589
05590 if ( ! geBitmap_Update_DriverToSystem((geBitmap *)Bmp) )
05591 {
05592 geErrorLog_AddString(-1,"Bitmap_AverageColor : DriverToSystem failed!",NULL);
05593 return GE_FALSE;
05594 }
05595 }
05596
05597 Format = Bmp->Info.Format;
05598 bpp = gePixelFormat_BytesPerPel(Format);
05599 ptr = Bmp->Data[0];
05600
05601 if ( ! ptr || bpp < 1 )
05602 {
05603 geErrorLog_AddString(-1,"Bitmap_AverageColor : no data!",NULL);
05604 return GE_FALSE;
05605 }
05606
05607 w = Bmp->Info.Width;
05608 h = Bmp->Info.Height;
05609 xtra = (Bmp->Info.Stride - w)*bpp;
05610 ck = Bmp->Info.ColorKey;
05611 dock = Bmp->Info.HasColorKey;
05612
05613 Rt = Gt = Bt = cnt = 0;
05614
05615 if ( gePixelFormat_HasPalette(Format) )
05616 {
05617
05618 geErrorLog_AddString(-1,"Bitmap_AverageColor : doesn't support palettized yet!",NULL);
05619 #pragma message("Bitmap_AverageColor : doesn't support palettized yet!")
05620 return GE_FALSE;
05621 }
05622 else
05623 {
05624 const gePixelFormat_Operations * ops;
05625 gePixelFormat_ColorGetter GetColor;
05626 gePixelFormat_PixelGetter GetPixel;
05627 gePixelFormat_Decomposer Decomposer;
05628
05629 assert( gePixelFormat_IsRaw(Format) );
05630
05631 ops = gePixelFormat_GetOperations(Format);
05632 GetColor = ops->GetColor;
05633 GetPixel = ops->GetPixel;
05634 Decomposer = ops->DecomposePixel;
05635
05636 if ( dock )
05637 {
05638 for(y=h;y--;)
05639 {
05640 for(x=w;x--;)
05641 {
05642 uint32 Pixel;
05643 Pixel = GetPixel(&ptr);
05644 if ( Pixel != ck )
05645 {
05646 Decomposer(Pixel,&R,&G,&B,&A);
05647 Rt += R; Gt += G; Bt += B;
05648 cnt ++;
05649 }
05650 }
05651 ptr += xtra;
05652 }
05653 }
05654 else
05655 {
05656 for(y=h;y--;)
05657 {
05658 for(x=w;x--;)
05659 {
05660 GetColor(&ptr,&R,&G,&B,&A);
05661 if ( A > 80 )
05662 {
05663 Rt += R; Gt += G; Bt += B;
05664 cnt ++;
05665 }
05666 }
05667 ptr += xtra;
05668 }
05669 }
05670 }
05671
05672 if ( pR ) *pR = (Rt + (cnt>>1)) / cnt;
05673 if ( pG ) *pG = (Gt + (cnt>>1)) / cnt;
05674 if ( pB ) *pB = (Bt + (cnt>>1)) / cnt;
05675 }
05676
05677 return GE_TRUE;
05678 }
05679
05680
05681