"L. Spiro Engine"

F:/My Projects/LSEngine/Modules/LSImageLib/Src/Image/LSIImage.h

00001 
00016 #ifndef __LSI_IMAGE_H__
00017 #define __LSI_IMAGE_H__
00018 
00019 #include "../LSIImageLib.h"
00020 #include "../Dds/LSIDds.h"
00021 #include "Map/LSTLMap.h"
00022 #include "Misc/LSCMisc.h"
00023 #include "Vector/LSTLVectorPoD.h"
00024 #include "Vector/LSTLVector.h"
00025 
00026 namespace lsi {
00027 
00028         // == Enumerations.
00032         enum LSI_FILTER {
00033                 LSI_F_BOX_FILTER,                                                       
00034                 LSI_F_BILINEAR_FILTER,                                          
00035                 LSI_F_KAISER_FILTER,                                            
00036                 LSI_F_LANCZOS3_FILTER,                                          
00037                 LSI_F_LANCZOS4_FILTER,                                          
00038                 LSI_F_LANCZOS6_FILTER,                                          
00039                 LSI_F_LANCZOS8_FILTER,                                          
00040                 LSI_F_LANCZOS12_FILTER,                                         
00041                 LSI_F_LANCZOS64_FILTER,                                         
00042                 LSI_F_MITCHELL_FILTER,                                          
00043                 LSI_F_CATMULLROM_FILTER,                                        
00044                 LSI_F_ANY,                                                                      
00045         };
00046 
00053         class CImage {
00054         public :
00055                 // == Various constructors.
00056                 LSE_CALLCTOR                                                            CImage();
00057                 LSE_CALLCTOR                                                            CImage( const CImage &_iOther );
00058 
00059 
00060                 // == Enumerations.
00064                 enum LSI_COMPRESSIONS {
00065                         LSI_C_RAWCOMPRESSION,                                   
00066                         LSI_C_CHANNELCOMPRESSION,                               
00067                         LSI_C_RLECOMPRESSION,                                   
00068                         LSI_C_INDEXCOMPRESSION,                                 
00069                         LSI_C_DTXCOMPRESSION,                                   
00070                 };
00071 
00072 
00073                 // == Operators.
00080                 CImage & LSE_CALL                                                       operator = ( const CImage &_iOther );
00081 
00082 
00083                 // == Functions.
00090                 LSVOID LSE_CALL                                                         SetAllocator( CAllocator * _paAllocator );
00091 
00095                 LSVOID LSE_CALL                                                         Reset();
00096 
00102                 LSE_INLINE LSUINT32 LSE_CALL                            GetWidth() const;
00103 
00109                 LSE_INLINE LSUINT32 LSE_CALL                            GetHeight() const;
00110 
00116                 LSE_INLINE LSI_PIXEL_FORMAT LSE_CALL            GetFormat() const;
00117 
00123                 LSE_INLINE const LSVOID * LSE_CALL                      GetBufferData() const;
00124 
00130                 LSE_INLINE const CImageLib::CTexelBuffer & LSE_CALL
00131                                                                                                         GetBufferDataAsVector() const;
00132 
00138                 LSE_INLINE const CVector<CImageLib::CTexelBuffer> & LSE_CALL
00139                                                                                                         GetMipMapBuffers() const;
00140 
00146                 LSE_INLINE LSUINT32 LSE_CALL                            TotalMipLevels() const;
00147 
00154                 LSE_INLINE const CImageLib::CTexelBuffer & LSE_CALL
00155                                                                                                         GetMipMapBuffers( LSUINT32 _ui32Level ) const;
00156 
00164                 LSBOOL LSE_CALL                                                         LoadFileFromMemory( const LSUINT8 * _pui8FileData, LSUINT32 _ui32DataLen );
00165 
00172                 LSBOOL LSE_CALL                                                         LoadFile( const LSCHAR * _pcFile );
00173 
00182                 LSBOOL LSE_CALL                                                         CreateBlank( LSI_PIXEL_FORMAT _pfFormat, LSUINT32 _ui32Width, LSUINT32 _ui32Height );
00183 
00193                 LSBOOL LSE_CALL                                                         CreateFromRgbAndAlpha( const CImage &_iRgb, const CImage &_iAlpha );
00194 
00204                 LSE_INLINE LSUINT64 LSE_CALL                            GetTexelAt( LSI_PIXEL_FORMAT _pfFormat, LSUINT32 _ui32X, LSUINT32 _ui32Y ) const;
00205 
00214                 LSE_INLINE LSVOID LSE_CALL                                      SetTexelAt( LSUINT64 _ui64Texel, LSI_PIXEL_FORMAT _pfFormat, LSUINT32 _ui32X, LSUINT32 _ui32Y );
00215 
00223                 LSBOOL LSE_CALL                                                         CompressToBuffer( CMisc::LSC_BUFFER &_bBuffer );
00224 
00228                 LSVOID LSE_CALL                                                         Flip();
00229 
00236                 LSVOID LSE_CALL                                                         ConvertToFormat( LSI_PIXEL_FORMAT _pfFormat, CImage &_iDest ) const;
00237 
00244                 CImage & LSE_CALL                                                       ConvertToFormatInPlace( LSI_PIXEL_FORMAT _pfFormat );
00245 
00258                 LSBOOL LSE_CALL                                                         Resample( LSUINT32 _ui32NewWidth, LSUINT32 _ui32NewHeight, LSI_FILTER _fFilter, CImage &_iDest,
00259                         LSFLOAT _fSrcGamma = 2.2f, LSFLOAT _fFilterScale = 1.0f ) const;
00260 
00272                 LSBOOL LSE_CALL                                                         ResampleInPlace( LSUINT32 _ui32NewWidth, LSUINT32 _ui32NewHeight, LSI_FILTER _fFilter,
00273                         LSFLOAT _fSrcGamma = 2.2f, LSFLOAT _fFilterScale = 1.0f );
00274 
00280                 LSUINT32 LSE_CALL                                                       GetCrc32() const;
00281 
00287                 LSUINT32 LSE_CALL                                                       GetCrc32Alt() const;
00288 
00297                 LSVOID LSE_CALL                                                         ConvertToNormalMap( LSFLOAT _fStr, LSBOOL _bWrapX = true, LSBOOL _bWrapY = true );
00298 
00306                 LSBOOL LSE_CALL                                                         ConvertToDds( LSI_PIXEL_FORMAT _pfFormat, CImage &_iDst );
00307 
00314                 LSBOOL LSE_CALL                                                         ConvertToDdsInPlace( LSI_PIXEL_FORMAT _pfFormat );
00315 
00323                 LSBOOL LSE_CALL                                                         IsBlackAndWhite() const;
00324 
00334         protected :
00335                 // == Enumerations.
00339                 enum {
00340                         LSI_LINEAR_TO_SRGB_TABLE_SIZE                   = 4096,                 
00341                 };
00342 
00343 
00344                 // == Types.
00348                 typedef struct LSI_SORTED_PIXEL {
00352                         union LSI_COL {
00353                                 LSUINT8                                                         ui8Rgb[16];
00354 
00355                                 LSUINT64                                                        ui64Rgb64;
00356                         }                                                                               u;
00357 
00361                         LSUINT32                                                                ui32Length;
00362 
00363 
00364                         // == Operators.
00371                         LSBOOL LSE_CALL                                                 operator < ( const LSI_SORTED_PIXEL &_spOther ) const;
00372 
00379                         LSBOOL LSE_CALL                                                 operator == ( const LSI_SORTED_PIXEL &_spOther ) const;
00380                 } * LPLSI_SORTED_PIXEL, * const LPCLSI_SORTED_PIXEL;
00381 
00385                 typedef union LSI_BLOCK {
00386                         struct LSI_COLOR {
00387                                 LSFLOAT                                                         fR, fG, fB, fA;
00388                         }                                                                               s;
00389                         LSFLOAT                                                                 fValues[4];
00390 
00391 
00392                         // == Operators.
00399                         LSE_INLINE LSBOOL LSE_CALL                              operator < ( const LSI_BLOCK &_bOther ) const;
00400 
00407                         LSE_INLINE LSBOOL LSE_CALL                              operator == ( const LSI_BLOCK &_bOther ) const;
00408 
00415                         LSE_INLINE LSBOOL LSE_CALL                              operator != ( const LSI_BLOCK &_bOther ) const;
00416                 } * LPLSI_BLOCK, * const LPCLSI_BLOCK;
00417 
00421                 typedef struct LSI_DXT_THREAD_DATA {
00425                         LSUINT32                                                                ui32SrcX;
00426 
00430                         LSUINT32                                                                ui32SrcY;
00431 
00435                         const CImage *                                                  piSrcImage;
00436 
00440                         LSUINT8 *                                                               pui8Dest;
00441 
00445                         LSI_PIXEL_FORMAT                                                pfFormat;
00446 
00450                         LSBOOL                                                                  bDone;
00451                 } * LPLSI_DXT_THREAD_DATA, * const LPCLSI_DXT_THREAD_DATA;
00452 
00453 
00454                 // == Members.
00458                 CImageLib::CTexelBuffer                                         m_tbBuffer;
00459 
00463                 CVector<CImageLib::CTexelBuffer>                        m_vMipMapBuffer;
00464 
00468                 LSUINT32                                                                        m_ui32Width;
00469 
00473                 LSUINT32                                                                        m_ui32Height;
00474 
00478                 LSI_PIXEL_FORMAT                                                        m_pfFormat;
00479 
00483                 LSUINT32                                                                        m_ui32RowWidth;
00484 
00488                 LSUINT32                                                                        m_ui32TexelSize;
00489 
00490 
00491                 // == Functions.
00495                 LSVOID LSE_CALL                                                         PostLoad();
00496 
00505                 LSBOOL LSE_CALL                                                         CompressChannels( CMisc::LSC_BUFFER &_bBuffer, LSUINT32 _ui32MaxSize = ~0UL );
00506 
00514                 LSBOOL LSE_CALL                                                         CompressRaw( CMisc::LSC_BUFFER &_bBuffer, LSUINT32 _ui32MaxSize = ~0UL );
00515 
00523                 LSBOOL LSE_CALL                                                         CompressRle( CMisc::LSC_BUFFER &_bBuffer, LSUINT32 _ui32MaxSize = ~0UL );
00524 
00533                 LSBOOL LSE_CALL                                                         CompressIndex( CMisc::LSC_BUFFER &_bBuffer, LSUINT32 _ui32MaxSize = ~0UL );
00534 
00541                 LSBOOL LSE_CALL                                                         CompressDxt( CMisc::LSC_BUFFER &_bBuffer );
00542 
00551                 LSBOOL LSE_CALL                                                         LoadCompressedChannels( const LSUINT8 * _pui8FileData, LSUINT32 _ui32DataLen, CImageLib::CTexelBuffer &_tbOut );
00552 
00561                 LSBOOL LSE_CALL                                                         LoadCompressedRaw( const LSUINT8 * _pui8FileData, LSUINT32 _ui32DataLen, CImageLib::CTexelBuffer &_tbOut );
00562 
00571                 LSBOOL LSE_CALL                                                         LoadCompressedBitwiseRle( const LSUINT8 * _pui8FileData, LSUINT32 _ui32DataLen, CImageLib::CTexelBuffer &_tbOut );
00572 
00581                 LSBOOL LSE_CALL                                                         LoadCompressedIndices( const LSUINT8 * _pui8FileData, LSUINT32 _ui32DataLen, CImageLib::CTexelBuffer &_tbOut );
00582 
00593                 LSBOOL LSE_CALL                                                         LoadDxt( LSUINT8 _ui8MipLevels, const LSUINT8 * _pui8FileData, LSUINT32 _ui32DataLen, CImageLib::CTexelBuffer &_tbOut,
00594                         CVector<CImageLib::CTexelBuffer> &_vMipMaps );
00595 
00603                 LSBOOL LSE_CALL                                                         LoadLsi( const LSUINT8 * _pui8FileData, LSUINT32 _ui32DataLen );
00604 
00619                 static LSVOID LSE_CALL                                          GetKeyColors( const LSI_BLOCK _bBlock[4][4], LSI_BLOCK &_bMax, LSI_BLOCK &_bMin, LSUINT32 _ui32Width, LSUINT32 _ui32Height,
00620                         LSFLOAT _fAlphaHigh, LSFLOAT _fAlphaLow, LSI_PIXEL_FORMAT _pfFormat );
00621 
00637                 static LSVOID LSE_CALL                                          RefineKeyColors( const CMap<LSFLOAT, LSUINT32> _bUniqueValues[4], const CMap<LSI_BLOCK, LSUINT32> &_bUniqueColors,
00638                         const LSI_BLOCK _bBlock[4][4], LSI_BLOCK &_bMax, LSI_BLOCK &_bMin, LSUINT32 _ui32Width, LSUINT32 _ui32Height,
00639                         LSUINT32 _ui32Iters, LSFLOAT _fAlphaHigh, LSFLOAT _fAlphaLow, LSI_PIXEL_FORMAT _pfFormat );
00640 
00649                 static LSVOID LSE_CALL                                          Get4Colors( const LSI_BLOCK &_bMax, const LSI_BLOCK &_bMin, LSI_BLOCK _bRet[4], LSBOOL _bOmitLast );
00650 
00660                 static LSVOID LSE_CALL                                          Get4Colors( LSUINT32 _ui32Channel, const LSI_BLOCK &_bMax, const LSI_BLOCK &_bMin, LSFLOAT _fRet[4], LSBOOL _bOmitLast );
00661 
00670                 static LSVOID LSE_CALL                                          MakeDxt1Block( const LSI_BLOCK _bBlock[4][4], const LSI_BLOCK &_bMax, const LSI_BLOCK &_bMin,
00671                         LSUINT8 * _pui8Return );
00672 
00685                 static LSUINT32 LSE_CALL                                        FindDxt1Match( const LSI_BLOCK &_bColor0, const LSI_BLOCK &_bColor1,
00686                         const LSI_BLOCK &_bColor );
00687 
00695                 static LSE_INLINE LSFLOAT LSE_CALL                      GetError( const LSI_BLOCK &_bColor0, const LSI_BLOCK &_bColor1 );
00696 
00710                 static LSFLOAT LSE_CALL                                         GetError( const CMap<LSI_BLOCK, LSUINT32> &_bUniqueColors, const LSI_BLOCK &_bMax, const LSI_BLOCK &_bMin,
00711                         LSUINT32 _ui32Width, LSUINT32 _ui32Height, LSBOOL _bOmitLast, LSFLOAT _fCurError );
00712 
00724                 static LSFLOAT LSE_CALL                                         GetErrorStrict( const LSI_BLOCK _bBlock[4][4], const LSI_BLOCK &_bMax, const LSI_BLOCK &_bMin,
00725                         LSUINT32 _ui32Width, LSUINT32 _ui32Height, LSBOOL _bOmitLast );
00726 
00737                 static LSE_INLINE LSFLOAT LSE_CALL                      GetError( LSUINT32 _ui32Channel,
00738                         const LSI_BLOCK _bBlocks[4], const LSI_BLOCK &_bSrc, LSUINT32 &_ui32Index, LSBOOL _bOmitLast );
00739 
00750                 static LSE_INLINE LSFLOAT LSE_CALL                      GetError( LSUINT32 _ui32Channel,
00751                         const LSI_BLOCK _bBlocks[4], LSFLOAT _fValue, LSUINT32 &_ui32Index, LSBOOL _bOmitLast );
00752 
00759                 static LSE_INLINE LSUINT16 LSE_CALL                     ConvertBlockTexelTo16Bit( const LSI_BLOCK &_bColor );
00760 
00767                 static LSE_INLINE LSI_BLOCK LSE_CALL            Convert16BitToBlockTexel( LSUINT16 _ui16Color );
00768 
00778                 static LSE_INLINE LSBOOL LSE_CALL                       Offset16BitColorChannel( LSUINT32 _ui32Channel, LSINT32 _i32Amount, LSUINT16 &_ui16Color );
00779 
00792                 static LSVOID LSE_CALL                                          FindEndPoints( LSFLOAT _fEndPoint, LSFLOAT _fMidPoint, LSUINT32 _ui32EndIndex, LSUINT32 _ui32MidIndex,
00793                         LSUINT32 _ui32Points, LSFLOAT _fRes, LSFLOAT &_fLow, LSFLOAT &_fHigh );
00794 
00802                 static LSE_INLINE LSFLOAT LSE_CALL                      Round( LSFLOAT _fValue, LSFLOAT _fRes );
00803 
00810                 static LSUINT32 LSH_CALL                                        DxtThread( LSVOID * _lpParameter );
00811 
00812         };
00813 
00814 
00815         // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
00816         // DEFINITIONS
00817         // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
00818         // == Operators.
00825         LSE_INLINE LSBOOL LSE_CALL CImage::LSI_BLOCK::operator < ( const LSI_BLOCK &_bOther ) const {
00826                 return fValues[0] < _bOther.fValues[0] && fValues[1] < _bOther.fValues[1] &&
00827                         fValues[2] < _bOther.fValues[2] && fValues[3] < _bOther.fValues[3];
00828         }
00829 
00836         LSE_INLINE LSBOOL LSE_CALL CImage::LSI_BLOCK::operator == ( const LSI_BLOCK &_bOther ) const {
00837                 return fValues[0] == _bOther.fValues[0] && fValues[1] == _bOther.fValues[1] &&
00838                         fValues[2] == _bOther.fValues[2] && fValues[3] == _bOther.fValues[3];
00839         }
00840 
00847         LSE_INLINE LSBOOL LSE_CALL CImage::LSI_BLOCK::operator != ( const LSI_BLOCK &_bOther ) const {
00848                 return fValues[0] != _bOther.fValues[0] || fValues[1] != _bOther.fValues[1] ||
00849                         fValues[2] != _bOther.fValues[2] || fValues[3] != _bOther.fValues[3];
00850         }
00851 
00852         // == Functions.
00858         LSE_INLINE LSUINT32 LSE_CALL CImage::GetWidth() const {
00859                 return m_ui32Width;
00860         }
00861 
00867         LSE_INLINE LSUINT32 LSE_CALL CImage::GetHeight() const {
00868                 return m_ui32Height;
00869         }
00870 
00876         LSE_INLINE LSI_PIXEL_FORMAT LSE_CALL CImage::GetFormat() const {
00877                 return m_pfFormat;
00878         }
00879 
00885         LSE_INLINE const LSVOID * LSE_CALL CImage::GetBufferData() const {
00886                 return m_tbBuffer.Length() ? &m_tbBuffer[0] : NULL;
00887         }
00888 
00894         LSE_INLINE const CImageLib::CTexelBuffer & LSE_CALL CImage::GetBufferDataAsVector() const {
00895                 return m_tbBuffer;
00896         }
00902         LSE_INLINE const CVector<CImageLib::CTexelBuffer> & LSE_CALL CImage::GetMipMapBuffers() const {
00903                 return m_vMipMapBuffer;
00904         }
00905 
00912         LSE_INLINE const CImageLib::CTexelBuffer & LSE_CALL CImage::GetMipMapBuffers( LSUINT32 _ui32Level ) const {
00913                 return _ui32Level == 0UL ? GetBufferDataAsVector() : GetMipMapBuffers()[_ui32Level-1UL];
00914         }
00915 
00921         LSE_INLINE LSUINT32 LSE_CALL CImage::TotalMipLevels() const {
00922                 return GetMipMapBuffers().Length() + 1UL;
00923         }
00924 
00934         LSE_INLINE LSUINT64 LSE_CALL CImage::GetTexelAt( LSI_PIXEL_FORMAT _pfFormat, LSUINT32 _ui32X, LSUINT32 _ui32Y ) const {
00935                 assert( _pfFormat < LSI_PF_TOTAL_INT );
00936                 return CImageLib::IntegerTexelToIntegerTexel( GetFormat(), _pfFormat, (*reinterpret_cast<const LSUINT64 *>(&m_tbBuffer[_ui32Y*m_ui32RowWidth+_ui32X*m_ui32TexelSize])) );
00937         }
00938 
00947         LSE_INLINE LSVOID LSE_CALL CImage::SetTexelAt( LSUINT64 _ui64Texel, LSI_PIXEL_FORMAT _pfFormat, LSUINT32 _ui32X, LSUINT32 _ui32Y ) {
00948                 assert( _pfFormat < LSI_PF_TOTAL_INT );
00949                 LSUINT64 ui64Converted = CImageLib::IntegerTexelToIntegerTexel( _pfFormat, GetFormat(), _ui64Texel );
00950 
00951                 static const LSUINT64 ui64Mask[] = {
00952                         0xFFFFFFFFFFFFFFFFULL,
00953                         0xFFFFFFFFFFFFFF00ULL,
00954                         0xFFFFFFFFFFFF0000ULL,
00955                         0xFFFFFFFFFF000000ULL,
00956                         0xFFFFFFFF00000000ULL,
00957                         0xFFFFFF0000000000ULL,
00958                         0xFFFF000000000000ULL,
00959                         0xFF00000000000000ULL,
00960                         0x0000000000000000ULL
00961                 };
00962                 static const LSUINT64 ui32Sizes[] = {
00963                         0x0000000000000000ULL,
00964                         0x00000000000000FFULL,
00965                         0x000000000000FFFFULL,
00966                         0x0000000000FFFFFFULL,
00967                         0x00000000FFFFFFFFULL,
00968                         0x000000FFFFFFFFFFULL,
00969                         0x0000FFFFFFFFFFFFULL,
00970                         0x00FFFFFFFFFFFFFFULL,
00971                         0xFFFFFFFFFFFFFFFFULL
00972                 };
00973                 LSUINT32 ui32Size = CImageLib::GetFormatSize( GetFormat() );
00974 
00975                 LSUINT64 * pui64Dst = reinterpret_cast<LSUINT64 *>(&m_tbBuffer[_ui32Y*m_ui32RowWidth+_ui32X*ui32Size]);
00976                 (*pui64Dst) = ((*pui64Dst) & ui64Mask[ui32Size]) | (ui64Converted & ui32Sizes[ui32Size]);
00977         }
00978 
00986         LSE_INLINE LSFLOAT LSE_CALL CImage::GetError( const LSI_BLOCK &_bColor0, const LSI_BLOCK &_bColor1 ) {
00987                 /*LSFLOAT fR0 = _bColor0.s.fR * _bColor0.s.fR;//::powf( _bColor0.s.fR, 2.2f );
00988                 LSFLOAT fR1 = _bColor1.s.fR * _bColor1.s.fR;//::powf( _bColor1.s.fR, 2.2f );
00989 
00990                 LSFLOAT fG0 = _bColor0.s.fG * _bColor0.s.fG;//::powf( _bColor0.s.fG, 2.2f );
00991                 LSFLOAT fG1 = _bColor1.s.fG * _bColor1.s.fG;//::powf( _bColor1.s.fG, 2.2f );
00992 
00993                 LSFLOAT fB0 = _bColor0.s.fB * _bColor0.s.fB;//::powf( _bColor0.s.fB, 2.2f );
00994                 LSFLOAT fB1 = _bColor1.s.fB * _bColor1.s.fB;//::powf( _bColor1.s.fB, 2.2f );
00995 
00996                 return (fR0 - fR1) * (fR0 - fR1) * LSI_R_WEIGHT +
00997                         (fG0 - fG1) * (fG0 - fG1) * LSI_G_WEIGHT +
00998                         (fB0 - fB1) * (fB0 - fB1) * LSI_B_WEIGHT;*/
00999                 return (_bColor0.s.fR - _bColor1.s.fR) * (_bColor0.s.fR - _bColor1.s.fR) * LSI_R_WEIGHT +
01000                         (_bColor0.s.fG - _bColor1.s.fG) * (_bColor0.s.fG - _bColor1.s.fG) * LSI_G_WEIGHT +
01001                         (_bColor0.s.fB - _bColor1.s.fB) * (_bColor0.s.fB - _bColor1.s.fB) * LSI_B_WEIGHT;
01002         }
01003 
01014         LSE_INLINE LSFLOAT LSE_CALL CImage::GetError( LSUINT32 _ui32Channel,
01015                 const LSI_BLOCK _bBlocks[4], const LSI_BLOCK &_bSrc, LSUINT32 &_ui32Index, LSBOOL _bOmitLast ) {
01016                 return GetError( _ui32Channel,
01017                         _bBlocks, _bSrc.fValues[_ui32Channel], _ui32Index, _bOmitLast );
01018         }
01019 
01030         LSE_INLINE LSFLOAT LSE_CALL CImage::GetError( LSUINT32 _ui32Channel,
01031                 const LSI_BLOCK _bBlocks[4], LSFLOAT _fValue, LSUINT32 &_ui32Index, LSBOOL _bOmitLast ) {
01032                 LSFLOAT fMinError = 2.0f;
01033                 for ( LSUINT32 I = _bOmitLast ? 3UL : 4UL; I--; ) {
01034                         LSFLOAT fError = _bBlocks[I].fValues[_ui32Channel] - _fValue;
01035                         if ( CMathLib::Abs( fError ) < CMathLib::Abs( fMinError ) ) {
01036                                 fMinError = fError;
01037                                 _ui32Index = I;
01038                                 if ( fError == 0.0f ) { break; }
01039                         }
01040                 }
01041                 return fMinError;
01042         }
01043 
01050         LSE_INLINE LSUINT16 LSE_CALL CImage::ConvertBlockTexelTo16Bit( const LSI_BLOCK &_bColor ) {
01051                 LSUINT16 ui16Ret = static_cast<LSUINT16>(static_cast<LSUINT16>(CStd::Clamp( _bColor.s.fR + (1.0f / 31.0f * 0.5f), 0.0f, 1.0f ) * 31.0f) << 11);
01052                 ui16Ret |= static_cast<LSUINT16>(CStd::Clamp( _bColor.s.fG + (1.0f / 63.0f * 0.5f), 0.0f, 1.0f ) * 63.0f) << 5;
01053                 ui16Ret |= static_cast<LSUINT16>(CStd::Clamp( _bColor.s.fB + (1.0f / 31.0f * 0.5f), 0.0f, 1.0f ) * 31.0f);
01054                 return ui16Ret;
01055         }
01056 
01063         LSE_INLINE CImage::LSI_BLOCK LSE_CALL CImage::Convert16BitToBlockTexel( LSUINT16 _ui16Color ) {
01064                 LSI_BLOCK bColor;
01065                 bColor.s.fR = (_ui16Color >> 11) * (1.0f / 31.0f);
01066                 bColor.s.fG = ((_ui16Color >> 5) & 0x3F) * (1.0f / 63.0f);
01067                 bColor.s.fB = (_ui16Color & 0x1F) * (1.0f / 31.0f);
01068                 bColor.s.fA = 1.0f;
01069                 return bColor;
01070         }
01071 
01081         LSE_INLINE LSBOOL LSE_CALL CImage::Offset16BitColorChannel( LSUINT32 _ui32Channel, LSINT32 _i32Amount, LSUINT16 &_ui16Color ) {
01082                 static const LSUINT32 ui32Shifts[4] = {
01083                         11,                     // Red.
01084                         5,                      // Green.
01085                         0,                      // Blue.
01086                         0,                      // Alpha.
01087                 };
01088                 static const LSUINT32 ui32Bits[4] = {
01089                         5,                      // Red.
01090                         6,                      // Green.
01091                         5,                      // Blue.
01092                         0,                      // Alpha.
01093                 };
01094                 static const LSUINT32 ui32Masks[4] = {
01095                         (1UL << ui32Bits[0]) - 1UL,                     // Red.
01096                         (1UL << ui32Bits[1]) - 1UL,                     // Green.
01097                         (1UL << ui32Bits[2]) - 1UL,                     // Blue.
01098                         (1UL << ui32Bits[3]) - 1UL,                     // Alpha.
01099                 };
01100                 // Get the modified min.
01101                 LSUINT32 ui32Mask = ui32Masks[_ui32Channel];
01102                 LSUINT32 ui32Min = (_ui16Color >> ui32Shifts[_ui32Channel]) & ui32Mask;
01103                 if ( static_cast<LSINT32>(ui32Min) + _i32Amount < 0 ||
01104                         static_cast<LSINT32>(ui32Min) + _i32Amount > static_cast<LSINT32>(ui32Mask) ) {
01105                         // Modifying by this amount would put the min out of its valid range.
01106                         return false;
01107                 }
01108                 ui32Min += static_cast<LSUINT32>(_i32Amount);
01109                 _ui16Color = static_cast<LSUINT16>(_ui16Color & ~(ui32Mask << ui32Shifts[_ui32Channel]));
01110                 _ui16Color |= ui32Min << ui32Shifts[_ui32Channel];
01111                 return true;
01112         }
01113 
01121         LSE_INLINE LSFLOAT LSE_CALL CImage::Round( LSFLOAT _fValue, LSFLOAT _fRes ) {
01122                 return ::floorf( _fValue * _fRes + 0.5f ) / _fRes;
01123         }
01124 
01125 }       // namespace lsi
01126 
01127 #endif  // __LSI_IMAGE_H__
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator