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