/src/FreeImage/Source/Quantizers.h
https://bitbucket.org/cabalistic/ogredeps/ · C Header · 225 lines · 82 code · 39 blank · 104 comment · 0 complexity · b9a30f2fa339c35009d4f3c8b91a66b1 MD5 · raw file
- // =============================================================
- // Quantizer objects and functions
- //
- // Design and implementation by:
- // - Hervé Drolon <drolon@infonie.fr>
- //
- // This file is part of FreeImage 3
- //
- // COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
- // OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
- // THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
- // OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
- // CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
- // THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
- // SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
- // PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
- // THIS DISCLAIMER.
- //
- // Use at your own risk!
- // =============================================================
- //
- ////////////////////////////////////////////////////////////////
- #include "FreeImage.h"
- ////////////////////////////////////////////////////////////////
- /**
- Xiaolin Wu color quantization algorithm
- */
- class WuQuantizer
- {
- public:
- typedef struct tagBox {
- int r0; // min value, exclusive
- int r1; // max value, inclusive
- int g0;
- int g1;
- int b0;
- int b1;
- int vol;
- } Box;
- protected:
- float *gm2;
- LONG *wt, *mr, *mg, *mb;
- WORD *Qadd;
- // DIB data
- unsigned width, height;
- unsigned pitch;
- FIBITMAP *m_dib;
- protected:
- void Hist3D(LONG *vwt, LONG *vmr, LONG *vmg, LONG *vmb, float *m2, int ReserveSize, RGBQUAD *ReservePalette);
- void M3D(LONG *vwt, LONG *vmr, LONG *vmg, LONG *vmb, float *m2);
- LONG Vol(Box *cube, LONG *mmt);
- LONG Bottom(Box *cube, BYTE dir, LONG *mmt);
- LONG Top(Box *cube, BYTE dir, int pos, LONG *mmt);
- float Var(Box *cube);
- float Maximize(Box *cube, BYTE dir, int first, int last , int *cut,
- LONG whole_r, LONG whole_g, LONG whole_b, LONG whole_w);
- bool Cut(Box *set1, Box *set2);
- void Mark(Box *cube, int label, BYTE *tag);
- public:
- // Constructor - Input parameter: DIB 24-bit to be quantized
- WuQuantizer(FIBITMAP *dib);
- // Destructor
- ~WuQuantizer();
- // Quantizer - Return value: quantized 8-bit (color palette) DIB
- FIBITMAP* Quantize(int PaletteSize, int ReserveSize, RGBQUAD *ReservePalette);
- };
- /**
- NEUQUANT Neural-Net quantization algorithm by Anthony Dekker
- */
- // ----------------------------------------------------------------
- // Constant definitions
- // ----------------------------------------------------------------
- /** number of colours used:
- for 256 colours, fixed arrays need 8kb, plus space for the image
- */
- //static const int netsize = 256;
- /**@name network definitions */
- //@{
- //static const int maxnetpos = (netsize - 1);
- /// bias for colour values
- static const int netbiasshift = 4;
- /// no. of learning cycles
- static const int ncycles = 100;
- //@}
- /**@name defs for freq and bias */
- //@{
- /// bias for fractions
- static const int intbiasshift = 16;
- static const int intbias = (((int)1) << intbiasshift);
- /// gamma = 1024
- static const int gammashift = 10;
- // static const int gamma = (((int)1) << gammashift);
- /// beta = 1 / 1024
- static const int betashift = 10;
- static const int beta = (intbias >> betashift);
- static const int betagamma = (intbias << (gammashift-betashift));
- //@}
- /**@name defs for decreasing radius factor */
- //@{
- /// for 256 cols, radius starts
- //static const int initrad = (netsize >> 3);
- /// at 32.0 biased by 6 bits
- static const int radiusbiasshift = 6;
- static const int radiusbias = (((int)1) << radiusbiasshift);
- /// and decreases by a
- //static const int initradius = (initrad * radiusbias);
- // factor of 1/30 each cycle
- static const int radiusdec = 30;
- //@}
- /**@name defs for decreasing alpha factor */
- //@{
- /// alpha starts at 1.0
- static const int alphabiasshift = 10;
- static const int initalpha = (((int)1) << alphabiasshift);
- //@}
- /**@name radbias and alpharadbias used for radpower calculation */
- //@{
- static const int radbiasshift = 8;
- static const int radbias = (((int)1) << radbiasshift);
- static const int alpharadbshift = (alphabiasshift+radbiasshift);
- static const int alpharadbias = (((int)1) << alpharadbshift);
- //@}
- class NNQuantizer
- {
- protected:
- /**@name image parameters */
- //@{
- /// pointer to input dib
- FIBITMAP *dib_ptr;
- /// image width
- int img_width;
- /// image height
- int img_height;
- /// image line length
- int img_line;
- //@}
- /**@name network parameters */
- //@{
- int netsize, maxnetpos, initrad, initradius;
- /// BGRc
- typedef int pixel[4];
- /// the network itself
- pixel *network;
- /// for network lookup - really 256
- int netindex[256];
- /// bias array for learning
- int *bias;
- /// freq array for learning
- int *freq;
- /// radpower for precomputation
- int *radpower;
- //@}
- protected:
- /// Initialise network in range (0,0,0) to (255,255,255) and set parameters
- void initnet();
- /// Unbias network to give byte values 0..255 and record position i to prepare for sort
- void unbiasnet();
- /// Insertion sort of network and building of netindex[0..255] (to do after unbias)
- void inxbuild();
- /// Search for BGR values 0..255 (after net is unbiased) and return colour index
- int inxsearch(int b, int g, int r);
- /// Search for biased BGR values
- int contest(int b, int g, int r);
-
- /// Move neuron i towards biased (b,g,r) by factor alpha
- void altersingle(int alpha, int i, int b, int g, int r);
- /// Move adjacent neurons by precomputed alpha*(1-((i-j)^2/[r]^2)) in radpower[|i-j|]
- void alterneigh(int rad, int i, int b, int g, int r);
- /** Main Learning Loop
- @param sampling_factor sampling factor in [1..30]
- */
- void learn(int sampling_factor);
- /// Get a pixel sample at position pos. Handle 4-byte boundary alignment.
- void getSample(long pos, int *b, int *g, int *r);
- public:
- /// Constructor
- NNQuantizer(int PaletteSize);
- /// Destructor
- ~NNQuantizer();
- /** Quantizer
- @param dib input 24-bit dib to be quantized
- @param sampling a sampling factor in range 1..30.
- 1 => slower (but better), 30 => faster. Default value is 1
- @return returns the quantized 8-bit (color palette) DIB
- */
- FIBITMAP* Quantize(FIBITMAP *dib, int ReserveSize, RGBQUAD *ReservePalette, int sampling = 1);
- };