/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

  1. // =============================================================
  2. // Quantizer objects and functions
  3. //
  4. // Design and implementation by:
  5. // - Hervé Drolon <drolon@infonie.fr>
  6. //
  7. // This file is part of FreeImage 3
  8. //
  9. // COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
  10. // OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
  11. // THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
  12. // OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
  13. // CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
  14. // THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
  15. // SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
  16. // PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
  17. // THIS DISCLAIMER.
  18. //
  19. // Use at your own risk!
  20. // =============================================================
  21. //
  22. ////////////////////////////////////////////////////////////////
  23. #include "FreeImage.h"
  24. ////////////////////////////////////////////////////////////////
  25. /**
  26. Xiaolin Wu color quantization algorithm
  27. */
  28. class WuQuantizer
  29. {
  30. public:
  31. typedef struct tagBox {
  32. int r0; // min value, exclusive
  33. int r1; // max value, inclusive
  34. int g0;
  35. int g1;
  36. int b0;
  37. int b1;
  38. int vol;
  39. } Box;
  40. protected:
  41. float *gm2;
  42. LONG *wt, *mr, *mg, *mb;
  43. WORD *Qadd;
  44. // DIB data
  45. unsigned width, height;
  46. unsigned pitch;
  47. FIBITMAP *m_dib;
  48. protected:
  49. void Hist3D(LONG *vwt, LONG *vmr, LONG *vmg, LONG *vmb, float *m2, int ReserveSize, RGBQUAD *ReservePalette);
  50. void M3D(LONG *vwt, LONG *vmr, LONG *vmg, LONG *vmb, float *m2);
  51. LONG Vol(Box *cube, LONG *mmt);
  52. LONG Bottom(Box *cube, BYTE dir, LONG *mmt);
  53. LONG Top(Box *cube, BYTE dir, int pos, LONG *mmt);
  54. float Var(Box *cube);
  55. float Maximize(Box *cube, BYTE dir, int first, int last , int *cut,
  56. LONG whole_r, LONG whole_g, LONG whole_b, LONG whole_w);
  57. bool Cut(Box *set1, Box *set2);
  58. void Mark(Box *cube, int label, BYTE *tag);
  59. public:
  60. // Constructor - Input parameter: DIB 24-bit to be quantized
  61. WuQuantizer(FIBITMAP *dib);
  62. // Destructor
  63. ~WuQuantizer();
  64. // Quantizer - Return value: quantized 8-bit (color palette) DIB
  65. FIBITMAP* Quantize(int PaletteSize, int ReserveSize, RGBQUAD *ReservePalette);
  66. };
  67. /**
  68. NEUQUANT Neural-Net quantization algorithm by Anthony Dekker
  69. */
  70. // ----------------------------------------------------------------
  71. // Constant definitions
  72. // ----------------------------------------------------------------
  73. /** number of colours used:
  74. for 256 colours, fixed arrays need 8kb, plus space for the image
  75. */
  76. //static const int netsize = 256;
  77. /**@name network definitions */
  78. //@{
  79. //static const int maxnetpos = (netsize - 1);
  80. /// bias for colour values
  81. static const int netbiasshift = 4;
  82. /// no. of learning cycles
  83. static const int ncycles = 100;
  84. //@}
  85. /**@name defs for freq and bias */
  86. //@{
  87. /// bias for fractions
  88. static const int intbiasshift = 16;
  89. static const int intbias = (((int)1) << intbiasshift);
  90. /// gamma = 1024
  91. static const int gammashift = 10;
  92. // static const int gamma = (((int)1) << gammashift);
  93. /// beta = 1 / 1024
  94. static const int betashift = 10;
  95. static const int beta = (intbias >> betashift);
  96. static const int betagamma = (intbias << (gammashift-betashift));
  97. //@}
  98. /**@name defs for decreasing radius factor */
  99. //@{
  100. /// for 256 cols, radius starts
  101. //static const int initrad = (netsize >> 3);
  102. /// at 32.0 biased by 6 bits
  103. static const int radiusbiasshift = 6;
  104. static const int radiusbias = (((int)1) << radiusbiasshift);
  105. /// and decreases by a
  106. //static const int initradius = (initrad * radiusbias);
  107. // factor of 1/30 each cycle
  108. static const int radiusdec = 30;
  109. //@}
  110. /**@name defs for decreasing alpha factor */
  111. //@{
  112. /// alpha starts at 1.0
  113. static const int alphabiasshift = 10;
  114. static const int initalpha = (((int)1) << alphabiasshift);
  115. //@}
  116. /**@name radbias and alpharadbias used for radpower calculation */
  117. //@{
  118. static const int radbiasshift = 8;
  119. static const int radbias = (((int)1) << radbiasshift);
  120. static const int alpharadbshift = (alphabiasshift+radbiasshift);
  121. static const int alpharadbias = (((int)1) << alpharadbshift);
  122. //@}
  123. class NNQuantizer
  124. {
  125. protected:
  126. /**@name image parameters */
  127. //@{
  128. /// pointer to input dib
  129. FIBITMAP *dib_ptr;
  130. /// image width
  131. int img_width;
  132. /// image height
  133. int img_height;
  134. /// image line length
  135. int img_line;
  136. //@}
  137. /**@name network parameters */
  138. //@{
  139. int netsize, maxnetpos, initrad, initradius;
  140. /// BGRc
  141. typedef int pixel[4];
  142. /// the network itself
  143. pixel *network;
  144. /// for network lookup - really 256
  145. int netindex[256];
  146. /// bias array for learning
  147. int *bias;
  148. /// freq array for learning
  149. int *freq;
  150. /// radpower for precomputation
  151. int *radpower;
  152. //@}
  153. protected:
  154. /// Initialise network in range (0,0,0) to (255,255,255) and set parameters
  155. void initnet();
  156. /// Unbias network to give byte values 0..255 and record position i to prepare for sort
  157. void unbiasnet();
  158. /// Insertion sort of network and building of netindex[0..255] (to do after unbias)
  159. void inxbuild();
  160. /// Search for BGR values 0..255 (after net is unbiased) and return colour index
  161. int inxsearch(int b, int g, int r);
  162. /// Search for biased BGR values
  163. int contest(int b, int g, int r);
  164. /// Move neuron i towards biased (b,g,r) by factor alpha
  165. void altersingle(int alpha, int i, int b, int g, int r);
  166. /// Move adjacent neurons by precomputed alpha*(1-((i-j)^2/[r]^2)) in radpower[|i-j|]
  167. void alterneigh(int rad, int i, int b, int g, int r);
  168. /** Main Learning Loop
  169. @param sampling_factor sampling factor in [1..30]
  170. */
  171. void learn(int sampling_factor);
  172. /// Get a pixel sample at position pos. Handle 4-byte boundary alignment.
  173. void getSample(long pos, int *b, int *g, int *r);
  174. public:
  175. /// Constructor
  176. NNQuantizer(int PaletteSize);
  177. /// Destructor
  178. ~NNQuantizer();
  179. /** Quantizer
  180. @param dib input 24-bit dib to be quantized
  181. @param sampling a sampling factor in range 1..30.
  182. 1 => slower (but better), 30 => faster. Default value is 1
  183. @return returns the quantized 8-bit (color palette) DIB
  184. */
  185. FIBITMAP* Quantize(FIBITMAP *dib, int ReserveSize, RGBQUAD *ReservePalette, int sampling = 1);
  186. };