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