This file is indexed.

/usr/include/crystalspace-2.0/csgfx/quantize.h is in libcrystalspace-dev 2.0+dfsg-1build1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
/*
    RGB to paletted image quantization routine
    Copyright (C) 2000 by Andrew Zabolotny <bit@eltech.ru>

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public
    License along with this library; if not, write to the Free
    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#ifndef __CS_QUANTIZE_H__
#define __CS_QUANTIZE_H__

/** \file
 * RGB to paletted image quantization routine
 */

/**\addtogroup gfx
 * @{
 */

#include "csextern.h"

#include "csgfx/rgbpixel.h"

struct csColorBox;

/**
 * Color quantizer.
 * <p>
 * The algorithm presented here is a variation of well-known and widely-used
 * Heckbert quantization algorithm. It works in the following way: first,
 * we build a 3-D histogram that describes which colors and how many times
 * the corresponding colors were used. Since we deal with RGB images, all
 * possible colors counts to 256^3 = 16777216 colors, too much to keep in
 * memory. Because of this, we ignore several lowest bits from each color
 * component, taking into consideration human eye's sensivity to different
 * color components we take 5 bits for R, 6 bits for G and 4 bits for B.
 * This summary reduces to 32*64*16 = 32768 histogram cells, which is
 * a reasonable size for an dynamically-allocated array.
 * <p>
 * Next, we take the entire color box and split it into subboxes.
 * The split happens along the longest of R,G,B axis into half
 * (and taking again into account eye sensivity). After which we take
 * again the biggest box, and split it again and so on until we
 * have that much boxes how much colors we want. Then we assign to each
 * box a color index, and compute the median RGB value for each box.
 * <p>
 * To keep memory requirements in reasonable bounds, we scale down R/G/B
 * components to 5/6/4 bits respectively. This produces results that are
 * different from those we'll get with, say, 6/7/6 resolution but its
 * a quite suitable solution, for a quality vs speed choice. I've tried
 * 5/6/5 as well as 6/6/4 and its really hard to say they are better -
 * the results are definitely different but it's hard to say they are
 * really better.
 * <p>
 * WARNING: If the sum of R+G+B bits exceeds 16, you will a need special
 * case for big endian machines for the INDEX_B macro (see below). With
 * big-endian machines the B component starts at bit 8, thus the right
 * shift counter becomes negative. Probably the best solution is to add
 * an \#if B_BIT + 8 - HIST_B_BITS - HIST_G_BITS - HIST_R_BITS < 0.
 * 
 * <b>Quantizing</b><br>
 * The following routines can be used to split the quantization process
 * into small steps. First, you should call Begin(). This will
 * allocate some memory for color histogram and also do some other
 * maintenance work. Then you call Count () as much times as
 * you want, to count the frequencies of colors. This is a quite fast
 * operation, thus you can use it, for example, to compute a optimal
 * palette for a large number of images (for example, software 3D renderer
 * uses it for computing the optimal palette in paletted modes, by passing
 * every texture to Count()).
 * <p>
 * When you're finished with images, call Palette(). This will
 * compute the optimal palette. If you need just that, you can call
 * End() and you're done. If you need to remap all those textures
 * to the optimal palette, you can call Remap() as much times
 * as you wish. Finally you anyway should call End() to free
 * all the memory used by quantizer.
 * <p>
 * Now, a typical quantization sequence could look like this:
 * \code
 * Begin ();
 *
 *    Count (image, pixels);
 *   Count (...);
 *   ...
 *
 *   int maxcolors = 256;
 *   Palette (outpalette, maxcolors);
 *   // now maxcolors contains the actual number of palette entries
 *
 *   Remap (image, pixels, outimage);
 *   Remap (...);
 *   ...
 *
 * End ();
 * \endcode
 * The quantizer itself keeps track of its current state, and will silently
 * ignore invalid calls. For example, if you call Remap() right
 * after calling Begin() nothing will happen. You still can call
 * Palette() right after Begin(), and you will get the
 * expected black (or let's call it `empty') palette.
 *<p>
 * The Bias routine can be used to introduce a bias inside the
 * currently open color histogram towards given colors. The "weight"
 * parameter shows how important those colors are (0 - not at all, 100 -
 * very). This can be used to bias the resulting palette towards some
 * hard-coded values, for example you may want to use it to create a
 * relatively uniform palette that is somewhat biased towards the colors
 * contained in some picture(s).
 *<p>
 * Some routines accept an additional parameter (csRGBpixel *transp). If it
 * is 0, nothing special is performed. If it is non-0, it should point
 * to an valid csRGBpixel object; the color of that pixel will be treated in
 * a special way: Count() will ignore pixels of that color,
 * Palette() will allocate color index 0 for that color, and
 * Remap will map all such pixel values to index 0.
 */
class CS_CRYSTALSPACE_EXPORT csColorQuantizer
{
private:
  friend struct csColorBox;
  struct ColorIndex
  {
    int index;
    csColorBox* box;

    ColorIndex () : box(0) {}
  };

  // The storage for color usage histogram.
  uint16* hist;
  // Total number of colors that were used to create the histogram.
  unsigned int hist_pixels;

  // The storage for color space boxes.
  csColorBox* box;
  // Number of valid color boxes.
  int boxcount;
  // The storage for color indices.
  ColorIndex* color_index;

  // The state of quantization variables
  enum
  {
    // Uninitialized: initial state
    qsNone,
    // Counting color frequencies
    qsCount,
    // Remapping input images to output
    qsRemap
  } qState;

  static int compare_boxes (const void* i1, const void* i2);

public:
  /// Construct a new quantizer object.
  csColorQuantizer ();
  /// Destruct and cleanup.
  ~csColorQuantizer ();

  /**
   * Quantize a RGB image into a paletted image.
   * This is a relatively expensive operation, in both CPU and
   * memory resources terms. It is pretty fast though (more than
   * 3.200.000 pixels/sec on a relatively weak P5/166) for what it does.
   * It uses a variation of well-known Heckbert quantization algorithm.
   * The side bonus after quantization is that the palette is ordered
   * in most-used-first fashion.
   * If outimage is 0, it is allocated. If outpalette is 0, it
   * is allocated as well. If it is non-0, the routine supposes that
   * the storage the pointers point to has enough size to store resulting
   * image and palette (the size of resulting image is exactly "pixels" bytes,
   * the size of resulting palette is palsize colors).
   * \param image input image
   * \param pixels number of pixels in input image
   * \param pixperline number of pixels in one line
   * \param outimage output image (allocated if 0)
   * \param outpalette output palette (allocated if 0)
   * \param maxcolors maximal number of colors in output palette
   *     (actual number of colors on return)
   * \param dither Use/do not use Floyd-Steinberg dithering
   */
  void DoRGB (csRGBpixel* image, int pixels, int pixperline,
    uint8*& outimage, csRGBpixel*& outpalette, int& maxcolors, bool dither);

  /// Begin quantization
  void Begin ();
  /// Finish quantization
  void End ();
  /// Count the colors in a image and update the color histogram
  void Count (csRGBpixel* image, int pixels, csRGBpixel* transp = 0);
  /// Bias the color histogram towards given colors (weight = 0..100)
  void Bias (csRGBpixel* colors, int count, int weight);
  /// Compute the optimal palette for all images passed to QuantizeCount()
  void Palette (csRGBpixel*& outpalette, int &maxcolors,
    csRGBpixel* transp = 0);
  /// Remap a image to the palette computed by Palette()
  void Remap (csRGBpixel* image, int pixels, uint8*& outimage,
    csRGBpixel* transp = 0);
  /// Same but apply Floyd-Steinberg dithering for nicer (but slower) results.
  void RemapDither (csRGBpixel* image, int pixels, int pixperline,
    csRGBpixel* palette, int colors, uint8*& outimage,
    csRGBpixel* transp = 0);
};

/** @} */

#endif // __CS_QUANTIZE_H__