source: trunk/libdjvu/DjVuPalette.h @ 280

Last change on this file since 280 was 280, checked in by rbri, 11 years ago

DJVU plugin: djvulibre updated to version 3.5.22

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