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(PLBmp * 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 (PLBmp * pBmpSource, PLBmp * pBmpDest) const;
00085 void split (QUBOX * pBox0, QUBOX * pBox1, int ColComp) const;
00086 void squeeze(QUBOX * pBox) const;
00087 void genPopularityPalette (PLBmp * pBmpSource, PLBmp * pBmpDest) const;
00088 void genColorArray(PLBmp * pBmpSource) const;
00089 void genDefaultPalette (PLBmp * 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(PLBmp * 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
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157