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