#include <grndbmp.h>
Inheritance diagram for GRenderOptPalette:
Public Member Functions | |
GRenderOptPalette (DocRect ClipRegion, Matrix ConvertMatrix, FIXED16 ViewScale, UINT32 SrcDepth, double dpi, BOOL Use8bpp) | |
GRenderOptPalette constructor. | |
~GRenderOptPalette () | |
GRenderOptPalette destructor. | |
virtual BOOL | GetNextBand () |
Passes this band to Gavin's palette optimisation routine, before we move onto the next band. | |
LPLOGPALETTE | GetOptimisedPalette (UINT32 PaletteSize, UINT32 NumColours, UINT32 ReservedColours=0, BOOL SnapToBrowserPalette=FALSE) |
Generates an optimised palette from the Statistics generated from each band rendered so far. | |
Static Public Attributes | |
static BOOL | DoTwoColourRoundingToPrimary = TRUE |
static BOOL | DoGDrawConversion = TRUE |
static BOOL | UseOldPalette = TRUE |
Protected Attributes | |
void * | Stats |
BOOL | UseSpecial8bpp |
BOOL | m_bTooManyColours |
LPLOGPALETTE | m_pExactPalette |
Definition at line 232 of file grndbmp.h.
|
GRenderOptPalette constructor.
Definition at line 1523 of file grndbmp.cpp. 01524 : GRenderBitmap( ClipRegion, ConvertMatrix, ViewScale, Depth, dpi) 01525 { 01526 ERROR3IF(Depth != 32, "Bad Depth for GRenderOptPalette, must be 32bpp"); 01527 01528 UseSpecial8bpp = Use8bpp; 01529 01530 m_pExactPalette = NULL; 01531 01532 if (Depth == 32) 01533 { 01534 if (UseSpecial8bpp) 01535 { 01536 Stats = CCMalloc(DIBUtil::GetOptimal8bppPaletteWorkspaceSize() * 4); 01537 if (Stats) 01538 DIBUtil::Optimal8bppPaletteInitialise((INT32*)Stats); 01539 } 01540 else 01541 { 01542 Stats = CCMalloc(DIBUtil::GetOptimalPaletteWorkspaceSize()); 01543 if (Stats) 01544 DIBUtil::OptimalPaletteInitialise(Stats); 01545 01546 } 01547 if( !UseOldPalette ) 01548 { 01549 const size_t TotalPal = sizeof(LOGPALETTE) + ( sizeof(PALETTEENTRY) * 256 ); 01550 m_pExactPalette = (LPLOGPALETTE)CCMalloc( TotalPal ); 01551 if( m_pExactPalette ) 01552 DIBUtil::ExactPaletteInitialise( m_pExactPalette ); 01553 } 01554 } 01555 01556 m_bTooManyColours = FALSE; 01557 01558 // Re-initialise 01559 DoGDrawConversion = TRUE; 01560 }
|
|
GRenderOptPalette destructor.
Definition at line 1576 of file grndbmp.cpp. 01577 { 01578 if (Stats) 01579 CCFree(Stats); 01580 // GAT 01581 if (m_pExactPalette) 01582 CCFree(m_pExactPalette) ; 01583 }
|
|
Passes this band to Gavin's palette optimisation routine, before we move onto the next band.
Reimplemented from GRenderBitmap. Definition at line 1600 of file grndbmp.cpp. 01601 { 01602 // Before we move onto the next band, we'll pass the current strip to Gavin's 01603 // palette optimising code 01604 if (Stats) 01605 { 01606 INT32 Width = pBitmapInfo->bmiHeader.biWidth; 01607 INT32 Height = pBitmapInfo->bmiHeader.biHeight; 01608 01609 INT32 BmpSize = Width * Height; 01610 01611 // Calculate the number of colours used by this strip of the bitmap. 01612 // But only if we have not gone over 256 colours yet 01613 // GAT 01614 if( !m_bTooManyColours && !UseOldPalette ) 01615 { 01616 BOOL bResult = DIBUtil::CalculateNumberOfColoursInBitmap( m_pExactPalette, ( RGBQUAD* )pBits, BmpSize ); 01617 if( !bResult ) 01618 { 01619 m_bTooManyColours = TRUE; 01620 DoGDrawConversion = FALSE; 01621 } 01622 } 01623 01624 BOOL ok; 01625 if (UseSpecial8bpp) 01626 ok = DIBUtil::GenOptimal8bppPaletteStats( (INT32*)Stats, (RGBQUAD*)pBits, BmpSize ); 01627 else 01628 ok = DIBUtil::GenOptimalPaletteStats( Stats, (RGBQUAD*)pBits, BmpSize ); 01629 01630 ERROR3IF(!ok, "GenOptimalPaletteStats failed"); 01631 } 01632 01633 return GRenderBitmap::GetNextBand(); 01634 }
|
|
Generates an optimised palette from the Statistics generated from each band rendered so far.
WEBSTER Changes (markn 16/1/97): This function has been modified so that you can specify the number colours you want in the palette WEBSTER v2 changes (markn 22/7/97)
Definition at line 1666 of file grndbmp.cpp. 01667 { 01668 ERROR3IF(!(PaletteSize==2 || PaletteSize==16 || PaletteSize==256), "Bad palette size passed to GRenderOptPalette::GetOptimisedPalette"); 01669 ERROR3IF(ReservedColours > PaletteSize, "Too many colours reserved in GRenderOptPalette::GetOptimisedPalette"); 01670 01671 LPLOGPALETTE pPalette = NULL; 01672 01673 if (Stats) 01674 { 01675 const size_t TotalPal = sizeof(LOGPALETTE) + ( sizeof(PALETTEENTRY) * PaletteSize ); 01676 pPalette = (LPLOGPALETTE)CCMalloc( TotalPal ); 01677 if (pPalette) 01678 { 01679 // Initialise the palette with zeros 01680 memset(pPalette, 0, TotalPal); 01681 01682 pPalette->palVersion = 0x300; 01683 pPalette->palNumEntries = PaletteSize; 01684 01685 if (NumColours > PaletteSize) 01686 NumColours = PaletteSize; 01687 01688 if (ReservedColours < NumColours) 01689 { 01690 BOOL ok = TRUE; 01691 // GAT 01692 // If the bitmap has less than 256 colours, then we want to bypass the 01693 // optimisation code, and just use the exact palette. 01694 PORTNOTE("BmpPrevDlg", "Rampant use of BmapPrevDlg removed (please don't re-instate directly - the value should be a param or member of this class)") 01695 #ifndef EXCLUDE_FROM_XARALX 01696 if( !m_bTooManyColours && m_pExactPalette && !UseOldPalette 01697 && m_pExactPalette->palNumEntries < BmapPrevDlg::m_NumOfColoursUserAskedFor ) // and we want this many colours 01698 #else 01699 if( !m_bTooManyColours && m_pExactPalette && !UseOldPalette ) // and we want this many colours 01700 #endif 01701 { 01702 // Transfer the exact palette into the variable we want, and then clear up the memory. 01703 INT32 blackEntry = 10; 01704 pPalette->palNumEntries = m_pExactPalette->palNumEntries; 01705 INT32 i = 0; 01706 for( i = 0; i < m_pExactPalette->palNumEntries; i++ ) 01707 { 01708 pPalette->palPalEntry[i].peRed = m_pExactPalette->palPalEntry[i].peRed; 01709 pPalette->palPalEntry[i].peGreen = m_pExactPalette->palPalEntry[i].peGreen; 01710 pPalette->palPalEntry[i].peBlue = m_pExactPalette->palPalEntry[i].peBlue; 01711 01712 if (pPalette->palPalEntry[i].peRed == 255 && 01713 pPalette->palPalEntry[i].peGreen == 255 && 01714 pPalette->palPalEntry[i].peBlue == 255 ) 01715 blackEntry = i; 01716 } 01717 if (blackEntry != 10 && ReservedColours == 1) 01718 { 01719 // swap the black entry for number 10 as this is the transparent entry for some odd reason 01720 pPalette->palPalEntry[blackEntry].peRed = pPalette->palPalEntry[10].peRed; 01721 pPalette->palPalEntry[blackEntry].peGreen = pPalette->palPalEntry[10].peGreen; 01722 pPalette->palPalEntry[blackEntry].peBlue = pPalette->palPalEntry[10].peBlue; 01723 01724 pPalette->palPalEntry[10].peRed = 255; 01725 pPalette->palPalEntry[10].peGreen = 255; 01726 pPalette->palPalEntry[10].peBlue = 255; 01727 } 01728 for( ; i<0x100 ; i++ ) 01729 { 01730 pPalette->palPalEntry[i].peRed = 01731 pPalette->palPalEntry[i].peGreen = 01732 pPalette->palPalEntry[i].peBlue = 0 ; 01733 } 01734 01735 // BmapPrevDlg::m_bNeedPaletteUpdated = TRUE; 01736 PORTNOTE("BmpPrevDlg", "Use of BmapPrevDlg removed") 01737 #ifndef EXCLUDE_FROM_XARALX 01738 BmapPrevDlg::m_bUseExistingPalette = FALSE; 01739 #endif 01740 } 01741 else if (UseSpecial8bpp) 01742 { 01743 if (PaletteSize != 256) 01744 { 01745 ERROR3("Palette size is wrong for an 8bpp bitmap"); 01746 CCFree( pPalette ); 01747 return NULL; 01748 } 01749 01750 // There has to be at least 20 colours in the palette to accomodate the system colours 01751 if (NumColours < 20) 01752 NumColours = 20; 01753 01754 // Gavin adds 16 system colours, then later we remove these and add the full set of 20 system colours 01755 // Therefore, get Gavin to generate 4 fewer colours so we end up with the correct number of 01756 // colours in the palette. 01757 NumColours -= 4; 01758 01759 // We can only generate a maximum of 252 colours (i.e. (256-20)+16 = 252) 01760 if (NumColours > 252) 01761 NumColours = 252; 01762 01763 // Leave room for the reserved colours 01764 NumColours -= ReservedColours; 01765 01766 ok = DIBUtil::GenOptimal8bppPalette((INT32*) Stats, pPalette, NumColours); 01767 } 01768 else 01769 { 01770 // Leave room for the reserved colours 01771 NumColours -= ReservedColours; 01772 01773 ok = DIBUtil::GenOptimalPalette( Stats, pPalette, (NumColours==1) ? 2 : NumColours ); 01774 } 01775 // GAT 01776 if( m_pExactPalette ) 01777 { 01778 // Get some memory back. 01779 CCFree( m_pExactPalette ); 01780 m_pExactPalette = NULL; 01781 } 01782 01783 // WEBSTER - markn - 22/7/97 01784 if (ok && SnapToBrowserPalette) 01785 { 01786 PaletteManager::SnapToBrowserPalette(pPalette); 01787 } 01788 01789 if (ok) 01790 { 01791 // Now we need to shift the colours about a bit .... 01792 switch (PaletteSize) 01793 { 01794 INT32 index; 01795 01796 case 2: 01797 if (NumColours == 1) 01798 { 01799 // 1 colour needs some special treatment 01800 if (pPalette->palPalEntry[1].peRed == 0xFF && 01801 pPalette->palPalEntry[1].peGreen == 0xFF && 01802 pPalette->palPalEntry[1].peBlue == 0xFF) 01803 { 01804 // First entry is white 01805 pPalette->palPalEntry[1] = pPalette->palPalEntry[0]; 01806 pPalette->palPalEntry[1].peFlags = 0; 01807 01808 01809 pPalette->palPalEntry[0].peRed = 255; 01810 pPalette->palPalEntry[0].peGreen = 255; 01811 pPalette->palPalEntry[0].peBlue = 255; 01812 pPalette->palPalEntry[0].peFlags = 255; // This makes Gavin ignore this 01813 // colour when converting the bitmap 01814 } 01815 else if (pPalette->palPalEntry[0].peRed == 0xFF && 01816 pPalette->palPalEntry[0].peGreen == 0xFF && 01817 pPalette->palPalEntry[0].peBlue == 0xFF) 01818 { 01819 // Second entry is white 01820 pPalette->palPalEntry[0].peFlags = 255; // This makes Gavin ignore this 01821 // colour when converting the bitmap 01822 } 01823 else 01824 { 01825 // Neither entry is white ! 01826 pPalette->palPalEntry[0].peRed = 255; 01827 pPalette->palPalEntry[0].peGreen = 255; 01828 pPalette->palPalEntry[0].peBlue = 255; 01829 pPalette->palPalEntry[0].peFlags = 255; // This makes Gavin ignore this 01830 // colour when converting the bitmap 01831 } 01832 01833 pPalette->palNumEntries = 2; 01834 } 01835 else 01836 pPalette->palNumEntries += ReservedColours; 01837 break; 01838 01839 case 16: 01840 // Shift the palette entries down, so the reserved colours are at the start 01841 for (index = NumColours - 1; index >= 0; index--) 01842 { 01843 pPalette->palPalEntry[index + ReservedColours] = pPalette->palPalEntry[index]; 01844 } 01845 01846 // Blank the reserved colours to white 01847 for (index = 0; index < INT32(ReservedColours); index++) 01848 { 01849 pPalette->palPalEntry[index].peRed = 255; 01850 pPalette->palPalEntry[index].peGreen = 255; 01851 pPalette->palPalEntry[index].peBlue = 255; 01852 pPalette->palPalEntry[index].peFlags = 255; // This makes Gavin ignore this 01853 // colour when converting the bitmap 01854 } 01855 01856 pPalette->palNumEntries += ReservedColours; 01857 break; 01858 01859 case 256: 01860 #ifdef _BATCHING 01861 { 01862 for (UINT32 index = 0;index < NumColours;index++) 01863 { 01864 BYTE R = pPalette->palPalEntry[index].peRed; 01865 BYTE G = pPalette->palPalEntry[index].peGreen; 01866 BYTE B = pPalette->palPalEntry[index].peBlue; 01867 if (R == 254 && G == 254 && B == 254) 01868 { 01869 pPalette->palPalEntry[index].peRed = 255; 01870 pPalette->palPalEntry[index].peGreen = 255; 01871 pPalette->palPalEntry[index].peBlue = 255; 01872 } 01873 } 01874 } 01875 #endif 01876 01877 if (UseSpecial8bpp && !( !m_bTooManyColours && !UseOldPalette ) ) 01878 { 01879 LPLOGPALETTE pWinPalette; 01880 01881 // Now we move the colours. 01882 UINT32 CurStart = 16; 01883 UINT32 NewStart = 10 + ReservedColours; 01884 01885 if (CurStart < NumColours) 01886 { 01887 BOOL ColoursMoved = FALSE; 01888 01889 UINT32 NumColsToMove = NumColours - CurStart; 01890 ERROR3IF((NumColsToMove+CurStart) > 256,"No room for system colours"); 01891 ERROR3IF((NumColsToMove+NewStart) > 256,"No room for system colours"); 01892 01893 if (NewStart < CurStart) 01894 { 01895 // Move the non-system colours down 01896 for (index = 0; index < INT32(NumColsToMove); index++) 01897 pPalette->palPalEntry[index + NewStart] = pPalette->palPalEntry[index + CurStart]; 01898 01899 // Blank out unused colours that are not system colours 01900 for (index = NumColsToMove+NewStart;index < 246;index++) 01901 { 01902 pPalette->palPalEntry[index].peRed = 0; 01903 pPalette->palPalEntry[index].peGreen = 0; 01904 pPalette->palPalEntry[index].peBlue = 0; 01905 } 01906 01907 ColoursMoved = TRUE; 01908 } 01909 01910 ERROR3IF(!ColoursMoved,"Rewrite code to accomodate system colours"); 01911 } 01912 01913 ERROR3IF(CurStart > NumColours,"Not enough room for system colours"); 01914 01915 // Now fill in the rest of the palette with the 20 system colours 01916 // (10 at the start, and 10 at the end) 01917 pWinPalette = GetErrorDiffPalette(); 01918 01919 for (index = 0; index < 10; index++) 01920 { 01921 pPalette->palPalEntry[index] = pWinPalette->palPalEntry[index]; 01922 } 01923 01924 for (index = 246; index < 256; index++) 01925 { 01926 pPalette->palPalEntry[index] = pWinPalette->palPalEntry[index]; 01927 } 01928 01929 // Blank the reserved colours to white 01930 for (index = 10; index < INT32(10 + ReservedColours); index++) 01931 { 01932 pPalette->palPalEntry[index].peRed = 255; 01933 pPalette->palPalEntry[index].peGreen = 255; 01934 pPalette->palPalEntry[index].peBlue = 255; 01935 pPalette->palPalEntry[index].peFlags = 255; // This makes Gavin ignore this 01936 // colour when converting the bitmap 01937 } 01938 } 01939 else 01940 { 01941 // WEBSTER - markn 15/2/97 01942 // If there's a reserved colour (i.e. creating a transparent bitmap) 01943 // make sure Gavin doen't use it 01944 // To do this, shift all the colours up one place, and flag the reserved colour 01945 // (hard wired to 10 for some reason unknown to myself) so Gavin ignores it 01946 if (ReservedColours == 1) 01947 { 01948 for (index = 255;index > 10;index--) 01949 pPalette->palPalEntry[index] = pPalette->palPalEntry[index-1]; 01950 01951 pPalette->palPalEntry[10].peRed = 255; 01952 pPalette->palPalEntry[10].peGreen = 255; 01953 pPalette->palPalEntry[10].peBlue = 255; 01954 pPalette->palPalEntry[10].peFlags = 255; // This makes Gavin ignore this 01955 } 01956 01957 ERROR3IF(ReservedColours > 1,"This code won't work with more than one reserved colour"); 01958 01959 // As this code is assuming that the transparent colour index is 10, 01960 // if the user has chosen less than 10 colours, we need to ensure that 01961 // the palette actually includes the transparent colour index. Otherwise, 01962 // the GIF export code will assume it can output the requested colours using 01963 // the minimum bpp. E.g. user request 2 colours, output will be 1 bpp and 01964 // so the 10 will cause problems. 01965 // This fixing of the number of entries is actually done in ExtractBitmapCopy 01966 } 01967 break; 01968 default: 01969 ERROR3("Bad palette size in GRenderOptPalette::GetOptimisedPalette"); 01970 } 01971 } 01972 else 01973 { 01974 ERROR3("Failed to generate optimised palette"); 01975 CCFree( pPalette ); 01976 pPalette = NULL; 01977 } 01978 } 01979 } 01980 01981 // Reinitialise the Stats 01982 if (UseSpecial8bpp) 01983 DIBUtil::Optimal8bppPaletteInitialise((INT32*)Stats); 01984 else 01985 DIBUtil::OptimalPaletteInitialise(Stats); 01986 } 01987 01988 return pPalette; 01989 }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|