source: trunk/libdjvu/GPixmap.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: 22.0 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: GPixmap.h,v 1.10 2007/05/19 03:07:33 leonb Exp $
57// $Name: release_3_5_22 $
58
59#ifndef _GPIXMAP_H_
60#define _GPIXMAP_H_
61#ifdef HAVE_CONFIG_H
62#include "config.h"
63#endif
64#if NEED_GNUG_PRAGMAS
65# pragma interface
66#endif
67
68/** @name GPixmap.h
69
70    Files #"GPixmap.h"# and #"GPixmap.cpp"# implement class \Ref{GPixmap}.
71    Instances of this class represent color images.  Each RGB pixel is
72    represented by structure \Ref{GPixel}. The ``bottom left'' coordinate system
73    is used consistently in the DjVu library.  Line zero of a GPixmap is the
74    bottom line in the color image.  Pixels are organized from left to right
75    within each line.
76   
77    {\bf ToDo} --- More sophisticated color correction schemes.
78   
79    @memo
80    Generic support for color images.
81    @author
82    L\'eon Bottou <leonb@research.att.com>
83    @version
84    #$Id: GPixmap.h,v 1.10 2007/05/19 03:07:33 leonb Exp $# */
85//@{
86
87
88#include "GSmartPointer.h"
89
90#ifdef HAVE_NAMESPACES
91namespace DJVU {
92# ifdef NOT_DEFINED // Just to fool emacs c++ mode
93}
94#endif
95#endif
96
97
98class GBitmap;
99class GRect;
100class ByteStream;
101
102
103/** Color pixel as a RGB triple. 
104    The colors are represented using three bytes named #r#, #g# and #b#.  The
105    value of these bytes represent additive amounts of light.  Color white is
106    represented by setting all three bytes to #255#.  Color black is
107    represented by setting all three bytes to #0#.  This convention should not
108    be confused with the convention adopted for class \Ref{GBitmap} where the
109    pixel values represent an ink level.  */
110
111struct DJVUAPI GPixel
112{
113  /** Blue component. */
114  unsigned char b;
115  /** Green component. */
116  unsigned char g;
117  /** Red component. */
118  unsigned char r;
119  /** Returns true iff colors are identical. */
120  friend int operator==(const GPixel & p1, const GPixel & p2);
121  /** Returns true iff colors are different. */
122  friend int operator!=(const GPixel & p1, const GPixel & p2);
123  /** Returns a hash code for the color. */
124  friend unsigned int hash(const GPixel &p);
125  /** @name Predefined colors. */
126  //@{
127  /// GPixel::WHITE is initialized to #rgb:255/255/255#.
128  static const GPixel WHITE; 
129  /// GPixel::BLACK is initialized to #rgb:0/0/0#.
130  static const GPixel BLACK; 
131  /// GPixel::BLUE is initialized to #rgb:0/0/255#.
132  static const GPixel BLUE; 
133  /// GPixel::GREEN is initialized to #rgb:0/255/0#.
134  static const GPixel GREEN; 
135  /// GPixel::RED is initialized to #rgb:255/0/0#.
136  static const GPixel RED;
137  //@}
138};
139
140
141/** RGB Color images. 
142    Instances of class #GPixmap# represent color images as a two dimensional
143    array of pixels \Ref{GPixel}.  The bracket operator returns a pointer to
144    the pixels composing one line of the image.  This pointer can be used as
145    an array to read or write the pixels of this particular line.  Following
146    the general convention of the DjVu Reference Library, line zero is always
147    the bottom line of the image.
148 */
149
150class DJVUAPI GPixmap : public GPEnabled
151{
152protected:
153  GPixmap(void);
154  GPixmap(int nrows, int ncolumns, const GPixel *filler=0);
155  GPixmap(const GBitmap &ref);
156  GPixmap(const GBitmap &ref, const GRect &rect);
157  GPixmap(const GPixmap &ref);
158  GPixmap(const GPixmap &ref, const GRect &rect);
159  GPixmap(ByteStream &ref);
160
161public:
162  /// Virtual destructor.
163  virtual ~GPixmap();
164
165  void destroy(void);
166  /** @name Construction. */
167  //@{
168  /** Creates an empty GBitmap object.  The returned GPixmap has zero rows
169      and zero columns.  Use function \Ref{init} to change the size of the
170      image. */
171  static GP<GPixmap> create(void) {return new GPixmap();}
172
173  /** Creates a GPixmap with #nrows# rows and #ncolumns# columns.  When the
174      optional argument #filler# is specified, all pixels are initialized
175      with the corresponding color. */
176  static GP<GPixmap> create(
177    const int nrows, const int ncolumns, const GPixel *filler=0)
178  { return new GPixmap(nrows,ncolumns,filler); }
179
180  /** Creates a GPixmap by copying the gray level image #ref#.
181      The constructed GPixmap has the same size as #ref#.  The pixels
182      are initialized with shades of grays copied from #ref#. */
183  static GP<GPixmap> create(const GBitmap &ref)
184  { return new GPixmap(ref); }
185
186  /** Creates a GPixmap by copying the rectangle #rect# of the gray level
187      image #ref#.  The constructed GPixmap has the same size as rectangle
188      #rect#.  The pixels are initialized with shades of grays converted from
189      the ink levels represented in #ref#.  This conversion depends on the
190      number of gray levels in #ref#. */
191  static GP<GPixmap> create(const GBitmap &ref, const GRect &rect)
192  { return new GPixmap(ref,rect); }
193
194  /** Copy constructors. Creates a GPixmap by replicating the size and the
195      contents of GPixmap #ref#. */
196  static GP<GPixmap> create(const GPixmap &ref)
197  { return new GPixmap(ref); }
198
199  /** Creates a GPixmap by copying the rectangle #rect# of the color image #ref#.
200      The constructed GPixmap has the same size as rectangle #rect#.
201      The pixels are initialized with colors copied from #ref#. */
202  static GP<GPixmap> create(const GPixmap &ref, const GRect &rect)
203  { return new GPixmap(ref,rect); }
204
205  /** Creates a GPixmap by reading PPM data from ByteStream #ref#.
206      See \Ref{PNM and RLE file formats} for more information. */
207  static GP<GPixmap> create(ByteStream &ref)
208  { return new GPixmap(ref); }
209
210  //@}
211
212  /** @name Initialization. */
213  //@{
214  /** Resets the GPixmap to #nrows# rows and #ncolumns# columns.  When the
215      optional argument #filler# is specified, all pixels are initialized with
216      the corresponding color.  The previous content of the GPixmap is discarded. */
217  void init(int nrows, int ncolumns,  const GPixel *filler=0);
218  /** Resets the GPixmap by copying the size and the contents of the color
219      image #ref#.  The previous content of the GPixmap is discarded. */
220  void init(const GPixmap &ref);
221  /** Resets the GPixmap by copying the rectangle #rect# of the color image #ref#.
222      The previous content of the GPixmap is discarded. */
223  void init(const GPixmap &ref, const GRect &rect);
224  /** Resets the GPixmap by copying the size and the contents of the gray
225      level image #ref#.  The optional argument #ramp# is an array of 256
226      pixel values used for mapping the gray levels to color values.
227      Setting #ramp# to zero selects a linear ramp of shades of gray. */
228  void init(const GBitmap &ref, const GPixel *ramp=0);
229  /** Resets the GPixmap by copying the rectangle #rect# of the gray level
230      image #ref#.  The optional argument #ramp# is an array of 256 pixel
231      values used for mapping the gray levels to color values.  Setting #ramp#
232      to zero selects a linear ramp computed according to the maximal number
233      of gray levels in #ref#. */
234  void init(const GBitmap &ref, const GRect &rect, const GPixel *ramp=0);
235  /** Resets the GPixmap by reading PPM data from ByteStream #ref#.  See
236      \Ref{PNM and RLE file formats} for more information. */
237  void init(ByteStream &ref);
238  /** Resets the GPixmap by copying the gray level image #ref#.  The pixels
239      are initialized with shades of grays copied from #ref#. */
240  GPixmap& operator=(const GBitmap &ref);
241  /** Copy operator. Resets the GPixmap by copying the size and the contents
242      of the color image #ref#.  The previous content of the GPixmap is
243      discarded. */
244  GPixmap& operator=(const GPixmap &ref);
245  //@}
246
247  /** @name Accessing pixels. */
248  //@{
249  /** Returns the number of rows (the image height). */
250  unsigned int rows() const;
251  /** Returns the number of columns (the image width). */
252  unsigned int columns() const;
253  /** Returns a constant pointer to the first GPixel in row #row#.  This
254      pointer can be used as an array to read the row elements. */
255  const GPixel * operator[] (int row) const;
256  /** Returns a pointer to the first GPixel in row #row#.  This pointer can be
257      used as an array to read or write the row elements. */
258  GPixel * operator[] (int row);
259  /** Returns the length (in pixels) of a row in memory.  This number is equal
260      to the difference between pointers to pixels located in the same column
261      in consecutive rows.  This difference may be larger than the number of
262      columns in the image. */
263  unsigned int rowsize() const;
264  //@}
265
266  /** @name Resampling images. */
267  //@{
268  /** Resets this GPixmap with a subsampled segment of color image #src#.
269      This function conceptually rescales image #src# by a factor #1:factor#,
270      and copies rectangle #rect# of the subsampled image into the current GPixmap.
271      The full subsampled image is copied if #rect# is a null pointer.
272      Both operations are however performed together for efficiency reasons.
273      Subsampling works by averaging the colors of the source pixels located
274      in small squares of size #factor# times #factor#. */
275  void downsample(const GPixmap *src, int factor, const GRect *rect=0);
276  /** Resets this GPixmap with a oversampled segment of color image #src#.
277      This function conceptually rescales image #src# by a factor #factor:1#,
278      and copies rectangle #rect# of the oversampled image into the current
279      GPixmap.  The full oversampled image is copied if #rect# is a null
280      pointer.  Both operations are however performed together for efficiency
281      reasons.  Oversampling works by replicating the color of the source
282      pixels into squares of size #factor# times #factor#. */
283  void upsample(const GPixmap *src, int factor, const GRect *rect=0);
284  /** Resets this GPixmap with a rescaled segment of #src# (zoom 75%).  This
285      function conceptually rescales image #src# by a factor #3:4#, and copies
286      rectangle #rect# of the rescaled image into the current GPixmap.  The
287      full rescaled image is copied if #rect# is a null pointer.  Both
288      operations are however performed together for efficiency reasons.  This
289      function has been superseded by class \Ref{GPixmapScaler}. */
290  void downsample43(const GPixmap *src, const GRect *rect=0); 
291  /** Resets this GPixmap with a rescaled segment of #src# (zoom 150%).  This
292      function conceptually rescales image #src# by a factor #3:2# and copies
293      rectangle #rect# of the rescaled image into the current GPixmap.  The
294      full rescaled image is copied if #rect# is a null pointer.  Both
295      operations are however performed together for efficiency reasons.  This
296      function has been superseded by class \Ref{GPixmapScaler}. */
297  void upsample23(const GPixmap *src, const GRect *rect=0);
298  //@}
299
300  /** @name Blitting and applying stencils. 
301      These function is essential for rendering DjVu images.  The elementary
302      functions are \Ref{attenuate} and \Ref{blit}.  The combined functions
303      \Ref{blend} and \Ref{stencil} should be viewed as optimizations.  */
304  //@{
305  /** Attenuates the color image in preparation for a blit. 
306      Bitmap #bm# is positionned at location #x#,#y# over this color image.
307      The matching color image pixels are then multiplied by #1.0-Alpha# where
308      #Alpha# denotes the gray value, in range #[0,1]#, represented by the
309      corresponding pixel of bitmap #bm#. */
310  void attenuate(const GBitmap *bm, int x, int y);
311  /** Blits solid color #color# through transparency mask #bm#. 
312      Bitmap #bm# is positionned at location #x#,#y# over this color image.
313      The matching color image pixels are then modified by adding color
314      #color# multiplied by #Alpha#, where #Alpha# denotes the gray value, in
315      range #[0,1]#, represented by the corresponding pixel of bitmap #bm#. */
316  void blit(const GBitmap *bm, int x, int y, const GPixel *color);
317  /** Blits pixmap #color# through transparency mask #bm#.
318      Bitmap #bm# is positionned at location #x#,#y# over this color image.
319      The matching color image pixels are then modified by adding the
320      corresponding pixel color in pixmap #color#, multiplied by #Alpha#,
321      where #Alpha# denotes the gray value, in range #[0,1]#, represented by
322      the corresponding pixel of bitmap #bm#. */
323  void blit(const GBitmap *bm, int x, int y, const GPixmap *color);
324  /** Performs alpha blending. This function is similar to first calling
325      \Ref{attenuate} with alpha map #bm# and then calling \Ref{blit} with
326      alpha map #bm# and color map #color#. Both operations are performed
327      together for efficiency reasons. */
328  void blend(const GBitmap *bm, int x, int y, const GPixmap *color);
329  /** Resample color pixmap and performs color corrected alpha blending.  This
330      function conceptually computes an intermediate color image by first
331      upsampling the GPixmap #pm# by a factor #pms:1# (see \Ref{upsample}),
332      extracting the sub-image designated by rectangle #pmr# and applying
333      color correction #corr# (see \Ref{color_correct}).  This intermediate
334      color image is then blended into this pixel map according to the alpha
335      map #bm# (see \Ref{blend}). */
336  void stencil(const GBitmap *bm, 
337               const GPixmap *pm, int pms, 
338               const GRect *pmr, double corr=1.0);
339  //@}
340 
341  /** @name Manipulating colors. */
342  //@{
343  /** Dithers the image to 216 colors.  This function applies an ordered
344      dithering algorithm to reduce the image to 216 predefined colors.  These
345      predefined colors are located on a color cube of 6x6x6 colors: the color
346      RGB coordinates can only take the following values: #0#, #51#, #102#,
347      #163#, #214# or #255#.  This is useful for displaying images on a device
348      supporting a maximum of 256 colors. Arguments #xmin# and #ymin# control
349      the position of the dithering grids.  This is useful for dithering tiled
350      images. Arguments #xmin# and #ymin# must be the position of the bottom
351      left corner of the tile contained in this GPixmap. Properly setting
352      these arguments eliminates dithering artifacts on the tile
353      boundaries. */
354  void ordered_666_dither(int xmin=0, int ymin=0);
355  /** Dithers the image to 32768 colors.  This function applies an ordered
356      dithering algorithm to reduce the image to 32768 predefined colors.
357      These predefined colors are located on a color cube of 32x32x32 colors:
358      the color RGB coordinates can only take values in which the three least
359      significant bits are set to #1#.  This is useful for displaying images
360      with less than 24 bits per pixel.  Arguments #xmin# and #ymin# control
361      the position of the dithering grids.  This is useful for dithering tiled
362      images. Arguments #xmin# and #ymin# must be the position of the bottom
363      left corner of the tile contained in this GPixmap. Properly setting
364      these arguments eliminates dithering artifacts on the tile
365      boundaries. */
366  void ordered_32k_dither(int xmin=0, int ymin=0);
367  /** Applies a luminance gamma correction factor of #corr#.  Values greater than
368      #1.0# make the image brighter.  Values smaller than #1.0# make the image
369      darker.  The documentation of program \Ref{ppmcoco} explains how to
370      properly use this function. */
371  void color_correct(double corr);
372  /** Applies a luminance gamma correction to an array of pixels.
373      This function is {\em static} and does not modify this pixmap. */
374  static void color_correct(double corr, GPixel *pixels, int npixels);
375
376  //@}
377 
378  /** @name Miscellaneous. */
379  //@{
380  /** Returns the number of bytes allocated for this image. */
381  inline unsigned int get_memory_usage() const;
382  /** Saves the image into ByteStream #bs# using the PPM format.
383      Argument #raw# selects the ``Raw PPM'' (1) or the ``Ascii PPM'' (0) format.
384      See \Ref{PNM and RLE file formats} for more information. */
385  void save_ppm(ByteStream &bs, int raw=1) const;
386  //@}
387
388  /** @name Stealing or borrowing the memory buffer (advanced). */
389  //@{
390  /** Steals the memory buffer of a GPixmap.  This function returns the
391      address of the memory buffer allocated by this GPixmap object.  The
392      offset of the first pixel in the bottom line is written into variable
393      #offset#.  Other lines can be accessed using pointer arithmetic (see
394      \Ref{rowsize}).  The GPixmap object no longer ``owns'' the buffer: you
395      must explicitly de-allocate the buffer using #operator delete []#.  This
396      de-allocation should take place after the destruction or the
397      re-initialization of the GPixmap object.  This function will return a
398      null pointer if the GPixmap object does not ``own'' the buffer in the
399      first place.  */
400  GPixel *take_data(size_t &offset);
401  /** Initializes this GPixmap by borrowing a memory segment.  The GPixmap
402      then directly addresses the memory buffer #data# provided by the user.
403      This buffer must be large enough to hold #w*h# GPixels.  The GPixmap
404      object does not ``own'' the buffer: you must explicitly de-allocate the
405      buffer using #operator delete []#.  This de-allocation should take place
406      after the destruction or the re-initialization of the GPixmap object.  */
407  inline void borrow_data(GPixel &data, int w, int h); 
408  /// Identical to the above, but GPixmap will do the delete [].
409  void donate_data(GPixel *data, int w, int h); 
410 
411  /** Rotates pixmap by 90, 180 or 270 degrees anticlockwise
412      and returns a new pixmap, input pixmap is not changed.
413      count can be 1, 2, or 3 for 90, 180, 270 degree rotation.
414      It returns the same pixmap if not rotated. */
415  GP<GPixmap> rotate(int count=0);
416
417  //@}
418 
419  // Please ignore these two functions. Their only purpose is to allow
420  // DjVu viewer compile w/o errors. eaf.
421  // Is this still useful ?. lyb.
422  int get_grays(void) const { return 256; };
423  void set_grays(int) {};\
424 
425protected:
426  // data
427  unsigned short nrows;
428  unsigned short ncolumns;
429  unsigned short nrowsize;
430  GPixel *pixels;
431  GPixel *pixels_data;
432  friend class DjVu_PixImage;
433};
434
435//@}
436
437// INLINE --------------------------
438
439
440inline int 
441operator==(const GPixel & p1, const GPixel & p2)
442{
443  return p1.r==p2.r && p1.g==p2.g && p1.b==p2.b;
444}
445
446inline int 
447operator!=(const GPixel & p1, const GPixel & p2)
448{
449  return p1.r!=p2.r || p1.g!=p2.g || p1.b!=p2.b;
450}
451
452inline unsigned int 
453hash(const GPixel &p)
454{
455  unsigned int x = (p.b<<16)|(p.g<<8)|(p.r);
456  return x ^ (p.b<<4) ^ (p.r<<12);
457}
458
459inline unsigned int
460GPixmap::rows() const
461{
462  return nrows;
463}
464
465inline unsigned int
466GPixmap::columns() const
467{
468  return ncolumns;
469}
470
471inline unsigned int
472GPixmap::rowsize() const
473{
474  return nrowsize;
475}
476
477inline GPixel *
478GPixmap::operator[](int row)
479{
480  if (row<0 || row>=nrows || !pixels) return 0;
481  return &pixels[row * nrowsize];
482}
483
484inline const GPixel *
485GPixmap::operator[](int row) const
486{
487  if (row<0 || row>=nrows) return 0;
488  return &pixels[row * nrowsize];
489}
490
491inline GPixmap & 
492GPixmap::operator=(const GBitmap &ref)
493{
494  init(ref);
495  return *this;
496}
497
498inline GPixmap & 
499GPixmap::operator=(const GPixmap &ref)
500{
501  init(ref);
502  return *this;
503}
504
505inline void
506GPixmap::borrow_data(GPixel &data, int w, int h)
507{
508  donate_data(&data,w,h);
509  pixels_data=0;
510}
511
512//////////////////////////////////////////////////
513// Memory usage
514//////////////////////////////////////////////////
515
516
517inline unsigned int 
518GPixmap::get_memory_usage() const
519{
520  return  sizeof(GPixmap)+(nrows * ncolumns * sizeof(GPixel));
521}
522
523// ---------------------------------
524
525#ifdef HAVE_NAMESPACES
526}
527# ifndef NOT_USING_DJVU_NAMESPACE
528using namespace DJVU;
529# endif
530#endif
531#endif
532
533
Note: See TracBrowser for help on using the repository browser.