00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #if !defined(INCL_PLFILTERQUANTIZE)
00012 #define INCL_PLFILTERQUANTIZE
00013
00014 #if _MSC_VER >= 1000
00015 #pragma once
00016 #endif // _MSC_VER >= 1000
00017
00018 #include "plfilter.h"
00019 #include "plbitmap.h"
00020
00021 #define PLDTHPAL_MEDIAN 0 // Median Cut
00022 #define PLDTHPAL_POPULARITY 1 // Popularity Sort
00023 #define PLDTHPAL_DEFAULT 2 // Use Default Palette
00024 #define PLDTHPAL_USERDEFINED 3 // Use Palette set by SetUserPalette()
00025
00026 #define PLDTH_NONE 0 // None
00027 #define PLDTH_ORDERED 1 // Ordered Dithering
00028 #define PLDTH_FS 2 // Floyd-Steinberg Dithering
00029
00030
00031
00032
00033
00034 class PLFilterQuantize : public PLFilter
00035 {
00036 public:
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053 PLFilterQuantize (int DitherPaletteType, int DitherType);
00054
00055 virtual ~PLFilterQuantize();
00056
00057
00058 virtual void Apply(PLBmpBase * pBmpSource, PLBmp * pBmpDest) const;
00059
00060
00061 void SetUserPalette(const PLPixel32* pPal);
00062
00063 static const PLPixel32* GetDefaultPalette ();
00064
00065 private:
00066
00067 typedef struct tagQUBOX
00068 {
00069 PLPixel32 Corner0, Corner1;
00070 PLPixel32 Average;
00071 PLULONG count;
00072 } QUBOX;
00073
00074 typedef struct tagHISTONODE
00075 {
00076 int index;
00077 PLULONG count;
00078 } HISTONODE;
00079
00080
00081 void initLUT();
00082 void deleteLUT();
00083
00084 void genMedianPalette (PLBmpBase * pBmpSource, PLBmp * pBmpDest) const;
00085 void split (QUBOX * pBox0, QUBOX * pBox1, int ColComp) const;
00086 void squeeze(QUBOX * pBox) const;
00087 void genPopularityPalette (PLBmpBase * pBmpSource, PLBmp * pBmpDest) const;
00088 void genColorArray(PLBmpBase * pBmpSource) const;
00089 void genDefaultPalette (PLBmpBase * pBmpSource) const;
00090 void addColor(PLPixel32 col, PLULONG count) const;
00091 void makeBox(PLPixel32 col, int i, PLULONG c) const;
00092 int getColorTableIndex (PLPixel32 col) const;
00093 int getShiftedColorTableIndex (PLPixel32 col) const;
00094
00095 void ditherDestBmp(PLBmpBase * pBmpSource, PLBmp * pBmpDest) const;
00096 void jitterPixel (int i, int y, PLPixel32 * pPixel) const;
00097 void ditherPixelOrdered (int x, int y, PLPixel32 * pPixel) const;
00098 void ditherCompOrdered (int x, int y, PLBYTE * pComp) const;
00099 void ditherPixelFS(double * pR, double * pG, double * pB, double * pCurErrors) const;
00100 void ditherCompFS (double * pComp, double Error) const;
00101 PLBYTE getNeighbor (PLPixel32 Color, PLPixel32 * pPal) const;
00102 int colorDist (PLPixel32 c0, PLPixel32 c1) const;
00103
00104 int clip (int c) const;
00105
00106 int m_DitherPaletteType;
00107 int m_DitherType;
00108 PLPixel32* m_pUserPal;
00109
00110 HISTONODE ** m_ppHisto;
00111
00112 QUBOX * m_pQuBoxes;
00113 };
00114
00115 inline int PLFilterQuantize::clip (int c) const
00116 {
00117 if (c > 255)
00118 return 255;
00119 if (c < 0)
00120 return 0;
00121 return c;
00122 }
00123
00124 #endif
00125
00126
00127
00128
00129