source: trunk/libdjvu/GScaler.h @ 206

Last change on this file since 206 was 206, checked in by Eugene Romanenko, 14 years ago

DJVU plugin: djvulibre updated to version 3.5.19

File size: 12.9 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: GScaler.h,v 1.11 2007/03/25 20:48:32 leonb Exp $
57// $Name: release_3_5_19 $
58
59#ifndef _GSCALER_H_
60#define _GSCALER_H_
61#ifdef HAVE_CONFIG_H
62#include "config.h"
63#endif
64#if NEED_GNUG_PRAGMAS
65# pragma interface
66#endif
67
68// From: Leon Bottou, 1/31/2002
69// Almost equal to my initial code.
70
71#include "GException.h"
72#include "GRect.h"
73#include "GBitmap.h"
74#include "GPixmap.h"
75
76#ifdef HAVE_NAMESPACES
77namespace DJVU {
78# ifdef NOT_DEFINED // Just to fool emacs c++ mode
79}
80#endif
81#endif
82
83
84/** @name GScaler.h
85
86    Files #"GScaler.h"# and #"GScaler.cpp"# implement a fast bilinear
87    interpolation scheme to rescale a \Ref{GBitmap} or a \Ref{GPixmap}.
88    Common setup functions are implemented by the base class \Ref{GScaler}.
89    The actual function for rescaling a gray level image is implemented by
90    class \Ref{GBitmapScaler}.  The actual function for rescaling a color
91    image is implemented by class \Ref{GPixmapScaler}.
92
93    {\bf Remark} --- The bilinear interpolation code relies on fixed precision
94    tables.  It becomes suboptimal when upsampling (i.e. zooming into) an
95    image by a factor greater than eight.  High contrast images displayed at
96    high magnification may contain visible jaggies.
97
98    @memo
99    Rescaling images with bilinear interpolation.
100    @author
101    L\'eon Bottou <leonb@research.att.com>
102    @version
103    #$Id: GScaler.h,v 1.11 2007/03/25 20:48:32 leonb Exp $# */
104//@{
105
106
107/** Base class for GBitmapScaler and GPixmapScaler.  This base class
108    implements the common elements of class \Ref{GBitmapScaler} and
109    \Ref{GPixmapScaler}.  Functions \Ref{set_input_size} and
110    \Ref{set_output_size} are used to specify the size of the input image and
111    the size of the output image.  Functions \Ref{set_horz_ratio} and
112    \Ref{set_vert_ratio} may be used to override the scaling ratios computed
113    from the image sizes.  You can then call function \Ref{get_input_rect} to
114    know which pixels of the input image are necessary to compute a specified
115    rectangular zone of the output image.  The actual computation is then
116    performed by calling function #scale# in class \Ref{GBitmapScaler} and
117    \Ref{GPixmapScaler}. 
118*/
119class GScaler  : public GPEnabled
120{
121protected: 
122  GScaler();
123public:
124  virtual ~GScaler();
125  /** Sets the size of the input image. Argument #w# (resp. #h#) contains the
126      horizontal (resp. vertical) size of the input image.  This size is used
127      to initialize the internal data structures of the scaler object. */
128  void set_input_size(int w, int h);
129  /** Sets the size of the output image. Argument #w# (resp. #h#) contains the
130      horizontal (resp. vertical) size of the output image. This size is used
131      to initialize the internal data structures of the scaler object. */
132  void set_output_size(int w, int h);
133  /** Sets the horizontal scaling ratio #numer/denom#.  This function may be
134      used to force an exact scaling ratio.  The scaling ratios are otherwise
135      derived from the sizes of the input and output images. */
136  void set_horz_ratio(int numer, int denom);
137  /** Sets the vertical scaling ratio to #numer/denom#.  This function may be
138      used to force an exact scaling ratio.  The scaling ratios are otherwise
139      derived from the sizes of the input and output images. */
140  void set_vert_ratio(int numer, int denom);
141  /** Computes which input pixels are required to compute specified output
142      pixels.  Let us assume that we only need a part of the output
143      image. This part is defined by rectangle #desired_output#.  Only a part
144      of the input image is necessary to compute the output pixels.  Function
145      #get_input_rect# computes the coordinates of that part of the input
146      image, and stores them into rectangle #required_input#.  */
147  void get_input_rect( const GRect &desired_output, GRect &required_input );
148protected:
149  // The sizes
150  int inw, inh;
151  int xshift, yshift;
152  int redw, redh;
153  int outw, outh;
154  // Fixed point coordinates
155  int *vcoord;
156  GPBuffer<int> gvcoord;
157  int *hcoord;
158  GPBuffer<int> ghcoord;
159  // Helper
160  void make_rectangles(const GRect &desired, GRect &red, GRect &inp);
161};
162
163
164
165/** Fast rescaling code for gray level images.  This class augments the base
166    class \Ref{GScaler} with a function for rescaling gray level
167    images.  Function \Ref{GBitmapScaler::scale} computes an arbitrary segment
168    of the output image given the corresponding pixels in the input image.
169
170    {\bf Example} --- The following functions returns an gray level image
171    (sixteen gray levels, size #nw# by #nh#) containing a rescaled version of
172    the input image #in#.
173    \begin{verbatim}
174    GBitmap *rescale_bitmap(const GBitmap &in, int nw, int nh)
175    {
176      int w = in.columns();       // Get input width
177      int h = in.raws();          // Get output width
178      GBitmapScaler scaler(w,h,nw,nh);  // Creates bitmap scaler
179      GRect desired(0,0,nw,nh);   // Desired output = complete bitmap
180      GRect provided(0,0,w,h);    // Provided input = complete bitmap
181      GBitmap *out = new GBitmap;
182      scaler.scale(provided, in, desired, *out);  // Rescale
183      out->change_grays(16);      // Reduce to 16 gray levels
184      return out;
185    }
186    \end{verbatim} */
187class GBitmapScaler : public GScaler
188{
189protected:
190  GBitmapScaler(void);
191  GBitmapScaler(int inw, int inh, int outw, int outh);
192public:
193  /// Virtual destructor.
194  virtual ~GBitmapScaler();
195
196  /** Creates an empty GBitmapScaler. You must call functions
197      \Ref{GScaler::set_input_size} and \Ref{GScaler::set_output_size} before
198      calling any of the scaling functions. */
199  static GP<GBitmapScaler> create(void) {return new GBitmapScaler(); }
200
201  /** Creates a GBitmapScaler. The size of the input image is given by
202      #inw# and #inh#.  This function internally calls
203      \Ref{GScaler::set_input_size} and \Ref{GScaler::set_output_size}. The
204      size of the output image is given by #outw# and #outh#.  . */
205  static GP<GBitmapScaler> create(
206    const int inw, const int inh, const int outw, const int outh)
207  { return new GBitmapScaler(inw,inh,outw,outh); }
208
209  /** Computes a segment of the rescaled output image.  The GBitmap object
210      #output# is overwritten with the segment of the output image specified
211      by the rectangle #desired_output#.  The rectangle #provided_input#
212      specifies which segment of the input image is provided by the GBitmap
213      object #input#.  An exception \Ref{GException} is thrown if the
214      rectangle #provided_input# is smaller then the rectangle
215      #required_input# returned by function \Ref{GScaler::get_input_rect}.
216      Note that the output image always contain 256 gray levels. You may want
217      to use function \Ref{GBitmap::change_grays} to reduce the number of gray
218      levels. */
219  void scale( const GRect &provided_input, const GBitmap &input,
220              const GRect &desired_output, GBitmap &output );
221protected:
222  // Helpers
223  unsigned char *get_line(int, const GRect &, const GRect &, const GBitmap &);
224  // Temporaries
225  unsigned char *lbuffer;
226  GPBuffer<unsigned char> glbuffer;
227  unsigned char *conv;
228  GPBuffer<unsigned char> gconv;
229  unsigned char *p1;
230  GPBuffer<unsigned char> gp1;
231  unsigned char *p2;
232  GPBuffer<unsigned char> gp2;
233  int l1;
234  int l2;
235};
236
237
238/** Fast rescaling code for color images.  This class augments the base class
239    \Ref{GScaler} with a function for rescaling color images.  Function
240    \Ref{GPixmapScaler::scale} computes an arbitrary segment of the output
241    image given the corresponding pixels in the input image.
242
243    {\bf Example} --- The following functions returns a color image
244    of size #nw# by #nh# containing a rescaled version of
245    the input image #in#.
246    \begin{verbatim}
247    GPixmap *rescale_pixmap(const GPixmap &in, int nw, int nh)
248    {
249      int w = in.columns();       // Get input width
250      int h = in.raws();          // Get output width
251      GPixmapScaler scaler(w,h,nw,nh);  // Creates bitmap scaler
252      GRect desired(0,0,nw,nh);   // Desired output = complete image
253      GRect provided(0,0,w,h);    // Provided input = complete image
254      GPixmap *out = new GPixmap;
255      scaler.scale(provided, in, desired, *out);  // Rescale
256      return out;
257    }
258    \end{verbatim}
259
260 */
261class GPixmapScaler : public GScaler
262{
263protected:
264  GPixmapScaler(void);
265  GPixmapScaler(int inw, int inh, int outw, int outh);
266public:
267  /// Virtual destructor.
268  virtual ~GPixmapScaler();
269
270  /** Creates an empty GPixmapScaler. You must call functions
271      \Ref{GScaler::set_input_size} and \Ref{GScaler::set_output_size} before
272      calling any of the scaling functions. */
273  static GP<GPixmapScaler> create(void) {return new GPixmapScaler(); }
274
275  /** Creates a GPixmapScaler. The size of the input image is given by
276      #inw# and #inh#.  This function internally calls
277      \Ref{GScaler::set_input_size} and \Ref{GScaler::set_output_size}. The
278      size of the output image is given by #outw# and #outh#.  . */
279  static GP<GPixmapScaler> create(
280    const int inw, const int inh, const int outw, const int outh)
281  { return new GPixmapScaler(inw,inh,outw,outh); }
282
283  /** Computes a segment of the rescaled output image.  The pixmap #output# is
284      overwritten with the segment of the output image specified by the
285      rectangle #desired_output#.  The rectangle #provided_input# specifies
286      which segment of the input image is provided in the pixmap #input#.  An
287      exception \Ref{GException} is thrown if the rectangle #provided_input#
288      is smaller then the rectangle #required_input# returned by function
289      \Ref{GScaler::get_input_rect}. */
290  void scale( const GRect &provided_input, const GPixmap &input,
291              const GRect &desired_output, GPixmap &output );
292protected:
293  // Helpers
294  GPixel *get_line(int, const GRect &, const GRect &, const GPixmap &);
295  // Temporaries
296  GPixel *lbuffer;
297  GPBuffer<GPixel> glbuffer;
298  GPixel *p1;
299  GPBuffer<GPixel> gp1;
300  GPixel *p2;
301  GPBuffer<GPixel> gp2;
302  int    l1;
303  int    l2;
304};
305
306
307
308
309
310//@}
311   
312
313
314
315// -------- END
316
317#ifdef HAVE_NAMESPACES
318}
319# ifndef NOT_USING_DJVU_NAMESPACE
320using namespace DJVU;
321# endif
322#endif
323#endif
Note: See TracBrowser for help on using the repository browser.