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
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
|
//C- -*- C++ -*-
//C- -------------------------------------------------------------------
//C- DjVuLibre-3.5
//C- Copyright (c) 2002 Leon Bottou and Yann Le Cun.
//C- Copyright (c) 2001 AT&T
//C-
//C- This software is subject to, and may be distributed under, the
//C- GNU General Public License, Version 2. The license should have
//C- accompanied the software or you may obtain a copy of the license
//C- from the Free Software Foundation at http://www.fsf.org .
//C-
//C- This program is distributed in the hope that it will be useful,
//C- but WITHOUT ANY WARRANTY; without even the implied warranty of
//C- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
//C- GNU General Public License for more details.
//C-
//C- DjVuLibre-3.5 is derived from the DjVu(r) Reference Library
//C- distributed by Lizardtech Software. On July 19th 2002, Lizardtech
//C- Software authorized us to replace the original DjVu(r) Reference
//C- Library notice by the following text (see doc/lizard2002.djvu):
//C-
//C- ------------------------------------------------------------------
//C- | DjVu (r) Reference Library (v. 3.5)
//C- | Copyright (c) 1999-2001 LizardTech, Inc. All Rights Reserved.
//C- | The DjVu Reference Library is protected by U.S. Pat. No.
//C- | 6,058,214 and patents pending.
//C- |
//C- | This software is subject to, and may be distributed under, the
//C- | GNU General Public License, Version 2. The license should have
//C- | accompanied the software or you may obtain a copy of the license
//C- | from the Free Software Foundation at http://www.fsf.org .
//C- |
//C- | The computer code originally released by LizardTech under this
//C- | license and unmodified by other parties is deemed "the LIZARDTECH
//C- | ORIGINAL CODE." Subject to any third party intellectual property
//C- | claims, LizardTech grants recipient a worldwide, royalty-free,
//C- | non-exclusive license to make, use, sell, or otherwise dispose of
//C- | the LIZARDTECH ORIGINAL CODE or of programs derived from the
//C- | LIZARDTECH ORIGINAL CODE in compliance with the terms of the GNU
//C- | General Public License. This grant only confers the right to
//C- | infringe patent claims underlying the LIZARDTECH ORIGINAL CODE to
//C- | the extent such infringement is reasonably necessary to enable
//C- | recipient to make, have made, practice, sell, or otherwise dispose
//C- | of the LIZARDTECH ORIGINAL CODE (or portions thereof) and not to
//C- | any greater extent that may be necessary to utilize further
//C- | modifications or combinations.
//C- |
//C- | The LIZARDTECH ORIGINAL CODE is provided "AS IS" WITHOUT WARRANTY
//C- | OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
//C- | TO ANY WARRANTY OF NON-INFRINGEMENT, OR ANY IMPLIED WARRANTY OF
//C- | MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
//C- +------------------------------------------------------------------
//
// $Id: DjVuPalette.h,v 1.9 2003/11/07 22:08:21 leonb Exp $
// $Name: release_3_5_15 $
#ifndef _DJVUPALETTE_H_
#define _DJVUPALETTE_H_
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#if NEED_GNUG_PRAGMAS
# pragma interface
#endif
#include "GContainer.h"
#include "GPixmap.h"
#include <string.h>
#ifdef HAVE_NAMESPACES
namespace DJVU {
# ifdef NOT_DEFINED // Just to fool emacs c++ mode
}
#endif
#endif
/** @name DjVuPalette.h
Files #"DjVuPalette.h"# and #"DjVuPalette.cpp"# implement a single class
\Ref{DjVuPalette} which provides facilities for computing optimal color
palettes, coding color palettes, and coding sequences of color indices.
@memo
DjVuPalette header file
@version
#$Id: DjVuPalette.h,v 1.9 2003/11/07 22:08:21 leonb Exp $#
@author:
L\'eon Bottou <leonb@research.att.com> */
//@{
/** Computing and coding color palettes and index arrays.
This class provides facilities for computing optimal color palettes,
coding color palettes, and coding sequences of color indices.
{\bf Creating a color palette} -- The recipe for creating a color palette
consists in (a) creating a DjVuPalette object, (b) constructing a color
histogram using \Ref{histogram_add}, and (c) calling function
\Ref{compute_palette}.
{\bf Accessing the color palette} -- Conversion between colors and color
palette indices is easily achieved with \Ref{color_to_index} and
\Ref{index_to_color}. There are also functions for computing a palette
and quantizing a complete pixmap.
{\bf Sequences of color indices} -- The DjVuPalette object also contains
an array \Ref{colordata} optionally containing a sequence of color
indices. This array will be encoded and decoded by functions \Ref{encode}
and \Ref{decode}. This feature simplifies the implementation of the ``one
color per symbol'' model in DjVu.
{\bf Coding color palettes and color indices} -- Two functions
\Ref{encode} and \Ref{decode} are provided for coding the color palette
and the array of color indices when appropriate. */
#ifdef _WIN32_WCE_EMULATION // Work around odd behavior under WCE Emulation
#define CALLINGCONVENTION __cdecl
#else
#define CALLINGCONVENTION /* */
#endif
class DjVuPalette : public GPEnabled
{
protected:
DjVuPalette(void);
public:
/// Generic creator
static GP<DjVuPalette> create(void) {return new DjVuPalette();}
/// Non-virtual destructor
~DjVuPalette();
// COPY
DjVuPalette(const DjVuPalette &ref);
DjVuPalette& operator=(const DjVuPalette &ref);
// PALETTE COMPUTATION
/** Resets the color histogram to zero. */
void histogram_clear();
/** Adds the color specified by #p# to the histogram.
Argument #weight# represent the number of pixels with this color. */
void histogram_add(const GPixel &p, int weight);
/** Adds the color specified by the triple #bgr# to the histogram.
Argument #weight# represent the number of pixels with this color. */
void histogram_add(const unsigned char *bgr, int weight);
/** Adds the color specified by the weighted triple #bgr# to the histogram.
Argument #weight# represent the number of pixels with this color. This
function will compute the actual color by dividing the elements of the
#bgr# array by #weight# and then use the unnormalized values to compute
the average color per bucket. This is all a way to avoid excessive loss
of accuracy. */
void histogram_norm_and_add(const int *bgr, int weight);
/** Computes an optimal palette for representing an image where colors
appear according to the histogram. Argument #maxcolors# is the maximum
number of colors allowed in the palette (up to 1024). Argument
#minboxsize# controls the minimal size of the color cube area affected
to a color palette entry. Returns the index of the dominant color. */
int compute_palette(int maxcolors, int minboxsize=0);
/** Computes the optimal palette for pixmap #pm#. This function builds the
histogram for pixmap #pm# and computes the optimal palette using
\Ref{compute_palette}. */
int compute_pixmap_palette(const GPixmap &pm, int ncolors, int minboxsize=0);
// CONVERSION
/** Returns the number of colors in the palette. */
int size() const;
/** Returns the best palette index for representing color #p#. */
int color_to_index(const GPixel &p);
/** Returns the best palette index for representing color #bgr#. */
int color_to_index(const unsigned char *bgr);
/** Overwrites #p# with the color located at position #index# in the palette. */
void index_to_color(int index, GPixel &p) const;
/** Overwrites #rgb[0..3]# with the color located at
position #index# in the palette. */
void index_to_color(int index, unsigned char *bgr) const;
/** Quantizes pixmap #pm#. All pixels are replaced by their closest
approximation available in the palette. */
void quantize(GPixmap &pm);
/** Calls \Ref{compute_pixmap_palette} and \Ref{quantize}. */
int compute_palette_and_quantize(GPixmap &pm, int maxcolors, int minboxsize=0);
// COLOR CORRECTION
/** Applies a luminance gamma correction factor of #corr# to the palette
entries. Values greater than #1.0# make the image brighter. Values
smaller than #1.0# make the image darker. The documentation of program
\Ref{ppmcoco} explains how to properly use this function. */
void color_correct(double corr);
// COLOR INDEX DATA
/** Contains an optional sequence of color indices.
Function \Ref{encode} and \Ref{decode} also encode and decode this
sequence when such a sequence is provided. */
GTArray<short> colordata;
/** Returns colors from the color index sequence. Pixel #out# is
overwritten with the color corresponding to the #nth# element of the
color sequence \Ref{colordata}. */
void get_color(int nth, GPixel &out) const;
// CODING
/** Writes the palette colors. This function writes each palette color as a
RGB triple into bytestream #bs#. */
void encode_rgb_entries(ByteStream &bs) const;
/** Reads palette colors. This function initializes the palette colors by
reading #palettesize# RGB triples from bytestream #bs#. */
void decode_rgb_entries(ByteStream &bs, const int palettesize);
/** Encodes the palette and the color index sequence. This function encodes
the a version byte, the palette size, the palette colors and the color
index sequence into bytestream #bs#. Note that the color histogram is
never saved. */
void encode(GP<ByteStream> bs) const;
/** Initializes the object by reading data from bytestream #bs#. This
function reads a version byte, the palette size, the palette and the
color index sequence from bytestream #bs#. Note that the color
histogram is never saved. */
void decode(GP<ByteStream> bs);
private:
// Histogram
int mask;
GMap<int,int> *hist;
// Quantization data
struct PColor { unsigned char p[4]; };
GTArray<PColor> palette;
GMap<int,int> *pmap;
// Helpers
void allocate_hist();
void allocate_pmap();
static int CALLINGCONVENTION bcomp (const void*, const void*);
static int CALLINGCONVENTION gcomp (const void*, const void*);
static int CALLINGCONVENTION rcomp (const void*, const void*);
static int CALLINGCONVENTION lcomp (const void*, const void*);
int color_to_index_slow(const unsigned char *bgr);
private: // dummy functions
static void encode(ByteStream *);
static void decode(ByteStream *);
};
//@}
// ------------ INLINES
inline void
DjVuPalette::histogram_clear()
{
delete hist;
hist = 0;
mask = 0;
}
inline void
DjVuPalette::histogram_add(const unsigned char *bgr, int weight)
{
if (weight > 0)
{
if (!hist || hist->size()>=0x4000)
allocate_hist();
int key = (bgr[0]<<16)|(bgr[1]<<8)|(bgr[2])|(mask);
(*hist)[key] += weight;
}
}
inline void
DjVuPalette::histogram_add(const GPixel &p, int weight)
{
histogram_add(&p.b, weight);
}
inline void
DjVuPalette::histogram_norm_and_add(const int *bgr, int weight)
{
if (weight > 0)
{
int p0 = bgr[0]/weight; if (p0>255) p0=255;
int p1 = bgr[1]/weight; if (p1>255) p1=255;
int p2 = bgr[2]/weight; if (p2>255) p2=255;
if (!hist || hist->size()>=0x4000)
allocate_hist();
int key = (p0<<16)|(p1<<8)|(p2)|(mask);
(*hist)[key] += weight;
}
}
inline int
DjVuPalette::size() const
{
return palette.size();
}
inline int
DjVuPalette::color_to_index(const unsigned char *bgr)
{
if (! pmap)
allocate_pmap();
int key = (bgr[0]<<16)|(bgr[1]<<8)|(bgr[2]);
GPosition p = pmap->contains(key);
if ( p)
return (*pmap)[p];
return color_to_index_slow(bgr);
}
inline int
DjVuPalette::color_to_index(const GPixel &p)
{
return color_to_index(&p.b);
}
inline void
DjVuPalette::index_to_color(int index, unsigned char *bgr) const
{
const PColor &color = palette[index];
bgr[0] = color.p[0];
bgr[1] = color.p[1];
bgr[2] = color.p[2];
}
inline void
DjVuPalette::index_to_color(int index, GPixel &p) const
{
index_to_color(index, &p.b);
}
inline void
DjVuPalette::get_color(int nth, GPixel &p) const
{
index_to_color(colordata[nth], p);
}
// ------------ THE END
#ifdef HAVE_NAMESPACES
}
# ifndef NOT_USING_DJVU_NAMESPACE
using namespace DJVU;
# endif
#endif
#endif
|