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