source: trunk/libdjvu/DjVuPalette.h @ 199

Last change on this file since 199 was 17, checked in by Eugene Romanenko, 16 years ago

update makefiles, remove absolute paths, update djvulibre to version 3.5.17

File size: 12.4 KB
Line 
1//C-  -*- C++ -*-
2//C- -------------------------------------------------------------------
3//C- DjVuLibre-3.5
4//C- Copyright (c) 2002  Leon Bottou and Yann Le Cun.
5//C- Copyright (c) 2001  AT&T
6//C-
7//C- This software is subject to, and may be distributed under, the
8//C- GNU General Public License, Version 2. The license should have
9//C- accompanied the software or you may obtain a copy of the license
10//C- from the Free Software Foundation at http://www.fsf.org .
11//C-
12//C- This program is distributed in the hope that it will be useful,
13//C- but WITHOUT ANY WARRANTY; without even the implied warranty of
14//C- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15//C- GNU General Public License for more details.
16//C-
17//C- DjVuLibre-3.5 is derived from the DjVu(r) Reference Library
18//C- distributed by Lizardtech Software.  On July 19th 2002, Lizardtech
19//C- Software authorized us to replace the original DjVu(r) Reference
20//C- Library notice by the following text (see doc/lizard2002.djvu):
21//C-
22//C-  ------------------------------------------------------------------
23//C- | DjVu (r) Reference Library (v. 3.5)
24//C- | Copyright (c) 1999-2001 LizardTech, Inc. All Rights Reserved.
25//C- | The DjVu Reference Library is protected by U.S. Pat. No.
26//C- | 6,058,214 and patents pending.
27//C- |
28//C- | This software is subject to, and may be distributed under, the
29//C- | GNU General Public License, Version 2. The license should have
30//C- | accompanied the software or you may obtain a copy of the license
31//C- | from the Free Software Foundation at http://www.fsf.org .
32//C- |
33//C- | The computer code originally released by LizardTech under this
34//C- | license and unmodified by other parties is deemed "the LIZARDTECH
35//C- | ORIGINAL CODE."  Subject to any third party intellectual property
36//C- | claims, LizardTech grants recipient a worldwide, royalty-free,
37//C- | non-exclusive license to make, use, sell, or otherwise dispose of
38//C- | the LIZARDTECH ORIGINAL CODE or of programs derived from the
39//C- | LIZARDTECH ORIGINAL CODE in compliance with the terms of the GNU
40//C- | General Public License.   This grant only confers the right to
41//C- | infringe patent claims underlying the LIZARDTECH ORIGINAL CODE to
42//C- | the extent such infringement is reasonably necessary to enable
43//C- | recipient to make, have made, practice, sell, or otherwise dispose
44//C- | of the LIZARDTECH ORIGINAL CODE (or portions thereof) and not to
45//C- | any greater extent that may be necessary to utilize further
46//C- | modifications or combinations.
47//C- |
48//C- | The LIZARDTECH ORIGINAL CODE is provided "AS IS" WITHOUT WARRANTY
49//C- | OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
50//C- | TO ANY WARRANTY OF NON-INFRINGEMENT, OR ANY IMPLIED WARRANTY OF
51//C- | MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
52//C- +------------------------------------------------------------------
53//
54// $Id: DjVuPalette.h,v 1.9 2003/11/07 22:08:21 leonb Exp $
55// $Name:  $
56
57#ifndef _DJVUPALETTE_H_
58#define _DJVUPALETTE_H_
59#ifdef HAVE_CONFIG_H
60#include "config.h"
61#endif
62#if NEED_GNUG_PRAGMAS
63# pragma interface
64#endif
65
66
67#include "GContainer.h"
68#include "GPixmap.h"
69#include <string.h>
70
71
72#ifdef HAVE_NAMESPACES
73namespace DJVU {
74# ifdef NOT_DEFINED // Just to fool emacs c++ mode
75}
76#endif
77#endif
78
79
80/** @name DjVuPalette.h
81    Files #"DjVuPalette.h"# and #"DjVuPalette.cpp"# implement a single class
82    \Ref{DjVuPalette} which provides facilities for computing optimal color
83    palettes, coding color palettes, and coding sequences of color indices.
84    @memo
85    DjVuPalette header file
86    @version
87    #$Id: DjVuPalette.h,v 1.9 2003/11/07 22:08:21 leonb Exp $#
88    @author:
89    L\'eon Bottou <leonb@research.att.com> */
90//@{
91
92
93/** Computing and coding color palettes and index arrays.
94    This class provides facilities for computing optimal color palettes,
95    coding color palettes, and coding sequences of color indices.
96   
97    {\bf Creating a color palette} -- The recipe for creating a color palette
98    consists in (a) creating a DjVuPalette object, (b) constructing a color
99    histogram using \Ref{histogram_add}, and (c) calling function
100    \Ref{compute_palette}.
101
102    {\bf Accessing the color palette} -- Conversion between colors and color
103    palette indices is easily achieved with \Ref{color_to_index} and
104    \Ref{index_to_color}.  There are also functions for computing a palette
105    and quantizing a complete pixmap.
106
107    {\bf Sequences of color indices} -- The DjVuPalette object also contains
108    an array \Ref{colordata} optionally containing a sequence of color
109    indices.  This array will be encoded and decoded by functions \Ref{encode}
110    and \Ref{decode}.  This feature simplifies the implementation of the ``one
111    color per symbol'' model in DjVu.
112
113    {\bf Coding color palettes and color indices} -- Two functions
114    \Ref{encode} and \Ref{decode} are provided for coding the color palette
115    and the array of color indices when appropriate.  */
116#ifdef _WIN32_WCE_EMULATION         // Work around odd behavior under WCE Emulation
117#define CALLINGCONVENTION __cdecl
118#else
119#define CALLINGCONVENTION  /* */
120#endif
121
122class DjVuPalette : public GPEnabled
123{
124protected:
125  DjVuPalette(void);
126public:
127  /// Generic creator
128  static GP<DjVuPalette> create(void) {return new DjVuPalette();}
129
130  /// Non-virtual destructor
131  ~DjVuPalette();
132  // COPY
133  DjVuPalette(const DjVuPalette &ref);
134  DjVuPalette& operator=(const DjVuPalette &ref);
135  // PALETTE COMPUTATION
136  /** Resets the color histogram to zero. */
137  void histogram_clear();
138  /** Adds the color specified by #p# to the histogram.
139      Argument #weight# represent the number of pixels with this color. */
140  void histogram_add(const GPixel &p, int weight);
141  /** Adds the color specified by the triple #bgr# to the histogram.
142      Argument #weight# represent the number of pixels with this color. */
143  void histogram_add(const unsigned char *bgr, int weight);
144  /** Adds the color specified by the weighted triple #bgr# to the histogram.
145      Argument #weight# represent the number of pixels with this color.  This
146      function will compute the actual color by dividing the elements of the
147      #bgr# array by #weight# and then use the unnormalized values to compute
148      the average color per bucket.  This is all a way to avoid excessive loss
149      of accuracy. */
150  void histogram_norm_and_add(const int *bgr, int weight);
151  /** Computes an optimal palette for representing an image where colors
152      appear according to the histogram.  Argument #maxcolors# is the maximum
153      number of colors allowed in the palette (up to 1024).  Argument
154      #minboxsize# controls the minimal size of the color cube area affected
155      to a color palette entry.  Returns the index of the dominant color. */
156  int compute_palette(int maxcolors, int minboxsize=0);
157  /** Computes the optimal palette for pixmap #pm#.  This function builds the
158      histogram for pixmap #pm# and computes the optimal palette using
159      \Ref{compute_palette}. */
160  int compute_pixmap_palette(const GPixmap &pm, int ncolors, int minboxsize=0);
161  // CONVERSION
162  /** Returns the number of colors in the palette. */
163  int size() const;
164  /** Returns the best palette index for representing color #p#. */
165  int color_to_index(const GPixel &p);
166  /** Returns the best palette index for representing color #bgr#. */
167  int color_to_index(const unsigned char *bgr);
168  /** Overwrites #p# with the color located at position #index# in the palette. */
169  void index_to_color(int index, GPixel &p) const;
170  /** Overwrites #rgb[0..3]# with the color located at
171      position #index# in the palette. */
172  void index_to_color(int index, unsigned char *bgr) const;
173  /** Quantizes pixmap #pm#. All pixels are replaced by their closest
174      approximation available in the palette. */
175  void quantize(GPixmap &pm);
176  /** Calls \Ref{compute_pixmap_palette} and \Ref{quantize}. */
177  int compute_palette_and_quantize(GPixmap &pm, int maxcolors, int minboxsize=0);
178  // COLOR CORRECTION
179  /** Applies a luminance gamma correction factor of #corr# to the palette
180      entries.  Values greater than #1.0# make the image brighter.  Values
181      smaller than #1.0# make the image darker.  The documentation of program
182      \Ref{ppmcoco} explains how to properly use this function. */
183  void color_correct(double corr);
184  // COLOR INDEX DATA
185  /** Contains an optional sequence of color indices.
186      Function \Ref{encode} and \Ref{decode} also encode and decode this
187      sequence when such a sequence is provided. */
188  GTArray<short> colordata;
189  /** Returns colors from the color index sequence.  Pixel #out# is
190      overwritten with the color corresponding to the #nth# element of the
191      color sequence \Ref{colordata}. */
192  void get_color(int nth, GPixel &out) const;
193  // CODING
194  /** Writes the palette colors.  This function writes each palette color as a
195      RGB triple into bytestream #bs#. */
196  void encode_rgb_entries(ByteStream &bs) const;
197  /** Reads palette colors.  This function initializes the palette colors by
198      reading #palettesize# RGB triples from bytestream #bs#. */
199  void decode_rgb_entries(ByteStream &bs, const int palettesize);
200  /** Encodes the palette and the color index sequence. This function encodes
201      the a version byte, the palette size, the palette colors and the color
202      index sequence into bytestream #bs#.  Note that the color histogram is
203      never saved. */
204  void encode(GP<ByteStream> bs) const;
205  /** Initializes the object by reading data from bytestream #bs#.  This
206      function reads a version byte, the palette size, the palette and the
207      color index sequence from bytestream #bs#.  Note that the color
208      histogram is never saved. */
209  void decode(GP<ByteStream> bs);
210
211private:
212  // Histogram
213  int mask;
214  GMap<int,int> *hist;
215  // Quantization data
216  struct PColor { unsigned char p[4]; };
217  GTArray<PColor> palette;
218  GMap<int,int> *pmap;
219  // Helpers
220  void allocate_hist();
221  void allocate_pmap();
222  static int CALLINGCONVENTION bcomp (const void*, const void*);
223  static int CALLINGCONVENTION gcomp (const void*, const void*);
224  static int CALLINGCONVENTION rcomp (const void*, const void*);
225  static int CALLINGCONVENTION lcomp (const void*, const void*);
226  int color_to_index_slow(const unsigned char *bgr);
227private: // dummy functions
228  static void encode(ByteStream *);
229  static void decode(ByteStream *);
230};
231
232
233//@}
234
235// ------------ INLINES
236
237
238inline void 
239DjVuPalette::histogram_clear()
240{
241  delete hist;
242  hist = 0;
243  mask = 0;
244}
245
246inline void 
247DjVuPalette::histogram_add(const unsigned char *bgr, int weight)
248{
249  if (weight > 0)
250    {
251      if (!hist || hist->size()>=0x4000) 
252        allocate_hist();
253      int key = (bgr[0]<<16)|(bgr[1]<<8)|(bgr[2])|(mask);
254      (*hist)[key] += weight;
255    }
256} 
257
258inline void 
259DjVuPalette::histogram_add(const GPixel &p, int weight)
260{
261  histogram_add(&p.b, weight);
262}
263
264inline void 
265DjVuPalette::histogram_norm_and_add(const int *bgr, int weight)
266{
267  if (weight > 0)
268    {
269      int p0 = bgr[0]/weight; if (p0>255) p0=255;
270      int p1 = bgr[1]/weight; if (p1>255) p1=255;
271      int p2 = bgr[2]/weight; if (p2>255) p2=255;
272      if (!hist || hist->size()>=0x4000) 
273        allocate_hist();
274      int key = (p0<<16)|(p1<<8)|(p2)|(mask);
275      (*hist)[key] += weight;
276    }
277}
278
279inline int
280DjVuPalette::size() const
281{
282  return palette.size();
283}
284
285inline int 
286DjVuPalette::color_to_index(const unsigned char *bgr)
287{
288  if (! pmap)
289    allocate_pmap();
290  int key = (bgr[0]<<16)|(bgr[1]<<8)|(bgr[2]);
291  GPosition p = pmap->contains(key);
292  if ( p)
293    return (*pmap)[p];
294  return color_to_index_slow(bgr);
295}
296
297inline int 
298DjVuPalette::color_to_index(const GPixel &p)
299{
300  return color_to_index(&p.b);
301}
302
303inline void 
304DjVuPalette::index_to_color(int index, unsigned char *bgr) const
305{
306  const PColor &color = palette[index];
307  bgr[0] = color.p[0];
308  bgr[1] = color.p[1];
309  bgr[2] = color.p[2];
310}
311
312inline void 
313DjVuPalette::index_to_color(int index, GPixel &p) const
314{
315  index_to_color(index, &p.b);
316}
317
318inline void
319DjVuPalette::get_color(int nth, GPixel &p) const
320{
321  index_to_color(colordata[nth], p);
322}
323
324
325
326// ------------ THE END
327
328#ifdef HAVE_NAMESPACES
329}
330# ifndef NOT_USING_DJVU_NAMESPACE
331using namespace DJVU;
332# endif
333#endif
334#endif
335     
336     
337             
338
339   
Note: See TracBrowser for help on using the repository browser.