source: trunk/Lucide/SOURCE/gui/neuquant.h @ 172

Last change on this file since 172 was 172, checked in by Eugene Romanenko, 15 years ago

neuquant optimization

File size: 4.7 KB
Line 
1/* NeuQuant Neural-Net Quantization Algorithm
2 * ------------------------------------------
3 *
4 * Copyright (c) 1994 Anthony Dekker
5 *
6 * NEUQUANT Neural-Net quantization algorithm by Anthony Dekker, 1994.
7 * See "Kohonen neural networks for optimal colour quantization"
8 * in "Network: Computation in Neural Systems" Vol. 5 (1994) pp 351-367.
9 * for a discussion of the algorithm.
10 *
11 * Any party obtaining a copy of these files from the author, directly or
12 * indirectly, is granted, free of charge, a full and unrestricted irrevocable,
13 * world-wide, paid up, royalty-free, nonexclusive right and license to deal
14 * in this software and documentation files (the "Software"), including without
15 * limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
16 * and/or sell copies of the Software, and to permit persons who receive
17 * copies from any such party to do so, with the only requirement being
18 * that this copyright notice remain intact.
19 */
20
21#ifndef __NEUQUANT_H
22#define __NEUQUANT_H
23
24
25// NEUQUANT Neural-Net quantization algorithm by Anthony Dekker
26
27#define FI_RGBA_RED             2
28#define FI_RGBA_GREEN           1
29#define FI_RGBA_BLUE            0
30
31// ----------------------------------------------------------------
32// Constant definitions
33// ----------------------------------------------------------------
34
35#define netbiasshift    4
36#define ncycles         100
37#define intbiasshift    16
38#define intbias         (((int)1) << intbiasshift)
39#define gammashift      10
40#define betashift       10
41#define beta            (intbias >> betashift)
42#define betagamma       (intbias << (gammashift-betashift))
43#define radiusbiasshift 6
44#define radiusbias      (((int)1) << radiusbiasshift)
45#define radiusdec       30
46#define alphabiasshift  10
47#define initalpha       (((int)1) << alphabiasshift)
48#define radbiasshift    8
49#define radbias         (((int)1) << radbiasshift)
50#define alpharadbshift  (alphabiasshift+radbiasshift)
51#define alpharadbias    (((int)1) << alpharadbshift)
52
53
54class LuPixbuf;
55
56
57class NeuQuantizer
58{
59
60    protected:
61        LuPixbuf *pixbuf;
62        unsigned char *pixbits;
63        /// image width
64        int img_width;
65        /// image height
66        int img_height;
67        /// image line length
68        int img_line;
69        int img_line_len;
70        int bpp;
71
72        int netsize, maxnetpos, initrad, initradius;
73
74        /// BGRc
75        typedef int pixel[4];
76        /// the network itself
77        pixel *network;
78
79        /// for network lookup - really 256
80        int netindex[256];
81
82        /// bias array for learning
83        int *bias;
84        /// freq array for learning
85        int *freq;
86        /// radpower for precomputation
87        int *radpower;
88
89    protected:
90
91        /// Search for biased BGR values
92        int contest(int b, int g, int r);
93
94        /// Move neuron i towards biased (b,g,r) by factor alpha
95        void altersingle(int alpha, int i, int b, int g, int r);
96
97        /// Move adjacent neurons by precomputed alpha*(1-((i-j)^2/[r]^2)) in radpower[|i-j|]
98        void alterneigh(int rad, int i, int b, int g, int r);
99
100        /// Get a pixel sample at position pos. Handle 4-byte boundary alignment.
101        void getSample(long pos, int *b, int *g, int *r);
102
103    public:
104        /// Constructor
105        NeuQuantizer( LuPixbuf *pb, int PaletteSize );
106
107        /// Destructor
108        ~NeuQuantizer();
109
110        /// Initialise network in range (0,0,0) to (255,255,255) and set parameters
111        void initnet();
112
113        /// Unbias network to give byte values 0..255 and record position i to prepare for sort
114        void unbiasnet();
115
116        /// Insertion sort of network and building of netindex[0..255] (to do after unbias)
117        void inxbuild();
118
119        /// Search for BGR values 0..255 (after net is unbiased) and return colour index
120        int inxsearch(int b, int g, int r);
121
122        /// Main Learning Loop  sampling factor in [1..30]
123        void learn(int sampling_factor);
124
125        pixel *getNetwork() {
126            return network;
127        }
128};
129
130/**
131 Get a pixel sample at position pos. Handle 4-byte boundary alignment.
132 @param pos pixel position in a WxHxbpp pixel buffer
133 @param b blue pixel component
134 @param g green pixel component
135 @param r red pixel component
136*/
137inline void NeuQuantizer::getSample(long pos, int *b, int *g, int *r)
138{
139    // get equivalent pixel coordinates
140    int x = pos % img_line;
141    int y = pos / img_line;
142
143    unsigned char *bpos = pixbits + ( ( y * img_line_len ) + x );
144
145    *b = bpos[FI_RGBA_BLUE] << netbiasshift;
146    *g = bpos[FI_RGBA_GREEN] << netbiasshift;
147    *r = bpos[FI_RGBA_RED] << netbiasshift;
148}
149
150#endif // __NEUQUANT_H
Note: See TracBrowser for help on using the repository browser.