Blame libdjvu/GRect.h

Packit df99a1
//C-  -*- C++ -*-
Packit df99a1
//C- -------------------------------------------------------------------
Packit df99a1
//C- DjVuLibre-3.5
Packit df99a1
//C- Copyright (c) 2002  Leon Bottou and Yann Le Cun.
Packit df99a1
//C- Copyright (c) 2001  AT&T
Packit df99a1
//C-
Packit df99a1
//C- This software is subject to, and may be distributed under, the
Packit df99a1
//C- GNU General Public License, either Version 2 of the license,
Packit df99a1
//C- or (at your option) any later version. The license should have
Packit df99a1
//C- accompanied the software or you may obtain a copy of the license
Packit df99a1
//C- from the Free Software Foundation at http://www.fsf.org .
Packit df99a1
//C-
Packit df99a1
//C- This program is distributed in the hope that it will be useful,
Packit df99a1
//C- but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit df99a1
//C- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit df99a1
//C- GNU General Public License for more details.
Packit df99a1
//C- 
Packit df99a1
//C- DjVuLibre-3.5 is derived from the DjVu(r) Reference Library from
Packit df99a1
//C- Lizardtech Software.  Lizardtech Software has authorized us to
Packit df99a1
//C- replace the original DjVu(r) Reference Library notice by the following
Packit df99a1
//C- text (see doc/lizard2002.djvu and doc/lizardtech2007.djvu):
Packit df99a1
//C-
Packit df99a1
//C-  ------------------------------------------------------------------
Packit df99a1
//C- | DjVu (r) Reference Library (v. 3.5)
Packit df99a1
//C- | Copyright (c) 1999-2001 LizardTech, Inc. All Rights Reserved.
Packit df99a1
//C- | The DjVu Reference Library is protected by U.S. Pat. No.
Packit df99a1
//C- | 6,058,214 and patents pending.
Packit df99a1
//C- |
Packit df99a1
//C- | This software is subject to, and may be distributed under, the
Packit df99a1
//C- | GNU General Public License, either Version 2 of the license,
Packit df99a1
//C- | or (at your option) any later version. The license should have
Packit df99a1
//C- | accompanied the software or you may obtain a copy of the license
Packit df99a1
//C- | from the Free Software Foundation at http://www.fsf.org .
Packit df99a1
//C- |
Packit df99a1
//C- | The computer code originally released by LizardTech under this
Packit df99a1
//C- | license and unmodified by other parties is deemed "the LIZARDTECH
Packit df99a1
//C- | ORIGINAL CODE."  Subject to any third party intellectual property
Packit df99a1
//C- | claims, LizardTech grants recipient a worldwide, royalty-free, 
Packit df99a1
//C- | non-exclusive license to make, use, sell, or otherwise dispose of 
Packit df99a1
//C- | the LIZARDTECH ORIGINAL CODE or of programs derived from the 
Packit df99a1
//C- | LIZARDTECH ORIGINAL CODE in compliance with the terms of the GNU 
Packit df99a1
//C- | General Public License.   This grant only confers the right to 
Packit df99a1
//C- | infringe patent claims underlying the LIZARDTECH ORIGINAL CODE to 
Packit df99a1
//C- | the extent such infringement is reasonably necessary to enable 
Packit df99a1
//C- | recipient to make, have made, practice, sell, or otherwise dispose 
Packit df99a1
//C- | of the LIZARDTECH ORIGINAL CODE (or portions thereof) and not to 
Packit df99a1
//C- | any greater extent that may be necessary to utilize further 
Packit df99a1
//C- | modifications or combinations.
Packit df99a1
//C- |
Packit df99a1
//C- | The LIZARDTECH ORIGINAL CODE is provided "AS IS" WITHOUT WARRANTY
Packit df99a1
//C- | OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
Packit df99a1
//C- | TO ANY WARRANTY OF NON-INFRINGEMENT, OR ANY IMPLIED WARRANTY OF
Packit df99a1
//C- | MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
Packit df99a1
//C- +------------------------------------------------------------------
Packit df99a1
Packit df99a1
#ifndef _GRECT_H_
Packit df99a1
#define _GRECT_H_
Packit df99a1
#ifdef HAVE_CONFIG_H
Packit df99a1
#include "config.h"
Packit df99a1
#endif
Packit df99a1
#if NEED_GNUG_PRAGMAS
Packit df99a1
# pragma interface
Packit df99a1
#endif
Packit df99a1
Packit df99a1
Packit df99a1
/** @name GRect.h
Packit df99a1
    Files #"GRect.h"# and #"GRect.cpp"# implement basic operations on
Packit df99a1
    rectangles. Class \Ref{GRect} is used to represent rectangles.  Class
Packit df99a1
    \Ref{GRectMapper} represent the correspondence between points relative to
Packit df99a1
    given rectangles.  Class \Ref{GRatio} is used to represent scaling factors
Packit df99a1
    as rational numbers.
Packit df99a1
    @memo
Packit df99a1
    Rectangle manipulation class.
Packit df99a1
    @author
Packit df99a1
    L\'eon Bottou <leonb@research.att.com> -- initial implementation.
Packit df99a1
*/
Packit df99a1
//@{
Packit df99a1
Packit df99a1
#include "DjVuGlobal.h"
Packit df99a1
Packit df99a1
#ifdef HAVE_NAMESPACES
Packit df99a1
namespace DJVU {
Packit df99a1
# ifdef NOT_DEFINED // Just to fool emacs c++ mode
Packit df99a1
}
Packit df99a1
#endif
Packit df99a1
#endif
Packit df99a1
Packit df99a1
Packit df99a1
/* Flag to indicate that this djvulibre version
Packit df99a1
   gets rid of all the crap about orientation bits.
Packit df99a1
   All rotation code has been fixed and consistently
Packit df99a1
   implements counter-clockwise rotations. */
Packit df99a1
Packit df99a1
#define GRECT_WITHOUT_ORIENTATION_BITS 1
Packit df99a1
Packit df99a1
Packit df99a1
/** @name Point Coordinates vs. Pixel Coordinates
Packit df99a1
Packit df99a1
    The DjVu technology relies on the accurate superposition of images at
Packit df99a1
    different resolutions.  Such an accuracy cannot be reached with the usual
Packit df99a1
    assumption that pixels are small enough to be considered infinitesimally
Packit df99a1
    small.  We must distinguish very precisely ``points'' and ``pixels''.
Packit df99a1
    This distinction is essential for performing scaling operations.
Packit df99a1
Packit df99a1
    The pixels of an image are identified by ``pixel coordinates''.  The
Packit df99a1
    bottom-left corner pixel has coordinates #(0,0)# and the top-right corner
Packit df99a1
    pixel has coordinates #(w-1,h-1)# where #w# and #h# are the image size.
Packit df99a1
    Pixel coordinates are necessarily integers since pixels never overlap.
Packit df99a1
Packit df99a1
    An infinitesimally small point is identified by its ``point coordinates''.
Packit df99a1
    There may be fractional point coordinates, although this library does not
Packit df99a1
    make use of them.  Points with integer coordinates are located {\em on the
Packit df99a1
    corners of each pixel}.  They are not located on the pixel centers.  The
Packit df99a1
    center of the pixel with pixel coordinates #(i,j)# is located at point
Packit df99a1
    coordinates #(i+1/2,j+1/2)#.  In other words, the pixel #(i,j)# extends
Packit df99a1
    from point #(i,j)# to point #(i+1,j+1)#.
Packit df99a1
Packit df99a1
    Therefore, the point located on the bottom left corner of an image has
Packit df99a1
    coordinates #(0,0)#.  This point is in fact the bottom left corner of the
Packit df99a1
    bottom left pixel of the image.  The point located on the top right corner
Packit df99a1
    of an image has coordinates #(w,h)# where #w# and #h# are the image size.
Packit df99a1
    This is in fact the top right corner of pixel #(w-1,h-1)# which is the
Packit df99a1
    image pixel with the highest coordinates.
Packit df99a1
*/
Packit df99a1
//@{
Packit df99a1
//@}
Packit df99a1
Packit df99a1
Packit df99a1
Packit df99a1
/** Rectangle class.  Each instance of this class represents a rectangle whose
Packit df99a1
    sides are parallel to the axis. Such a rectangle represents all the points
Packit df99a1
    whose coordinates lies between well defined minimal and maximal values.
Packit df99a1
    Member functions can combine several rectangles by computing the
Packit df99a1
    intersection of rectangles (\Ref{intersect}) or the smallest rectangle
Packit df99a1
    enclosing two rectangles (\Ref{recthull}).  */
Packit df99a1
Packit df99a1
class DJVUAPI GRect 
Packit df99a1
{
Packit df99a1
public:
Packit df99a1
  /** Constructs an empty rectangle */
Packit df99a1
  GRect();
Packit df99a1
  /** Constructs a rectangle given its minimal coordinates #xmin# and #ymin#,
Packit df99a1
      and its measurements #width# and #height#. Setting #width# or #height# to zero
Packit df99a1
      produces an empty rectangle.  */
Packit df99a1
  GRect(int xmin, int ymin, unsigned int width=0, unsigned int height=0);
Packit df99a1
  /** Returns the rectangle width. */
Packit df99a1
  int  width() const;
Packit df99a1
  /** Returns the rectangle height. */
Packit df99a1
  int  height() const;
Packit df99a1
  /** Returns the area of the rectangle. */
Packit df99a1
  int  area() const;
Packit df99a1
  /** Returns true if the rectangle is empty. */
Packit df99a1
  bool  isempty() const;
Packit df99a1
  /** Returns true if the rectangle contains pixel (#x#,#y#).  A rectangle
Packit df99a1
      contains all pixels with horizontal pixel coordinates in range #xmin#
Packit df99a1
      (inclusive) to #xmax# (exclusive) and vertical coordinates #ymin#
Packit df99a1
      (inclusive) to #ymax# (exclusive). */
Packit df99a1
  int  contains(int x, int y) const;
Packit df99a1
  /** Returns true if this rectangle contains the passed rectangle #rect#.
Packit df99a1
      The function basically checks, that the intersection of this rectangle
Packit df99a1
      with #rect# is #rect#. */
Packit df99a1
  int  contains(const GRect & rect) const;
Packit df99a1
  /** Returns true if rectangles #r1# and #r2# are equal. */
Packit df99a1
  friend int operator==(const GRect & r1, const GRect & r2);
Packit df99a1
  /** Returns true if rectangles #r1# and #r2# are not equal. */
Packit df99a1
  friend int operator!=(const GRect & r1, const GRect & r2);
Packit df99a1
  /** Resets the rectangle to the empty rectangle */
Packit df99a1
  void clear();
Packit df99a1
  /** Fatten the rectangle. Both vertical sides of the rectangle are pushed
Packit df99a1
      apart by #dx# units. Both horizontal sides of the rectangle are pushed
Packit df99a1
      apart by #dy# units. Setting arguments #dx# (resp. #dy#) to a negative
Packit df99a1
      value reduces the rectangle horizontal (resp. vertical) size. */
Packit df99a1
  int  inflate(int dx, int dy);
Packit df99a1
  /** Translate the rectangle. The new rectangle is composed of all the points
Packit df99a1
      of the old rectangle translated by #dx# units horizontally and #dy#
Packit df99a1
      units vertically. */
Packit df99a1
  int  translate(int dx, int dy);
Packit df99a1
  /** Sets the rectangle to the intersection of rectangles #rect1# and #rect2#.
Packit df99a1
      This function returns true if the intersection rectangle is not empty. */
Packit df99a1
  int  intersect(const GRect &rect1, const GRect &rect2;;
Packit df99a1
  /** Sets the rectangle to the smallest rectangle containing the points of
Packit df99a1
      both rectangles #rect1# and #rect2#. This function returns true if the
Packit df99a1
      created rectangle is not empty. */
Packit df99a1
  int  recthull(const GRect &rect1, const GRect &rect2;;
Packit df99a1
  /** Multiplies xmin, ymin, xmax, ymax by factor and scales the rectangle*/
Packit df99a1
  void scale(float factor);
Packit df99a1
  /** Multiplies xmin, xmax by xfactor and ymin, ymax by yfactor and scales the rectangle*/
Packit df99a1
  void scale(float xfactor, float yfactor);
Packit df99a1
  /** Minimal horizontal point coordinate of the rectangle. */
Packit df99a1
  int xmin;
Packit df99a1
  /** Minimal vertical point coordinate of the rectangle. */
Packit df99a1
  int ymin;
Packit df99a1
  /** Maximal horizontal point coordinate of the rectangle. */
Packit df99a1
  int xmax;
Packit df99a1
  /** Maximal vertical point coordinate of the rectangle. */
Packit df99a1
  int ymax;
Packit df99a1
};
Packit df99a1
Packit df99a1
Packit df99a1
/** Maps points from one rectangle to another rectangle.  This class
Packit df99a1
    represents a relation between the points of two rectangles. Given the
Packit df99a1
    coordinates of a point in the first rectangle (input rectangle), function
Packit df99a1
    \Ref{map} computes the coordinates of the corresponding point in the
Packit df99a1
    second rectangle (the output rectangle).  This function actually implements
Packit df99a1
    an affine transform which maps the corners of the first rectangle onto the
Packit df99a1
    matching corners of the second rectangle. The scaling operation is
Packit df99a1
    performed using integer fraction arithmetic in order to maximize
Packit df99a1
    accuracy. */
Packit df99a1
class DJVUAPI GRectMapper 
Packit df99a1
{
Packit df99a1
public:
Packit df99a1
  /** Constructs a rectangle mapper. */
Packit df99a1
  GRectMapper();
Packit df99a1
  /** Resets the rectangle mapper state. Both the input rectangle
Packit df99a1
      and the output rectangle are marked as undefined. */
Packit df99a1
  void clear();
Packit df99a1
  /** Sets the input rectangle. */
Packit df99a1
  void set_input(const GRect &rect);
Packit df99a1
  /** Returns the input rectangle. */
Packit df99a1
  GRect get_input();
Packit df99a1
  /** Sets the output rectangle. */
Packit df99a1
  void set_output(const GRect &rect);
Packit df99a1
  /** Returns the output rectangle. */
Packit df99a1
  GRect get_output();
Packit df99a1
  /** Composes the affine transform with a rotation of #count# quarter turns
Packit df99a1
      counter-clockwise.  This operation essentially is a modification of the
Packit df99a1
      match between the corners of the input rectangle and the corners of the
Packit df99a1
      output rectangle. */
Packit df99a1
  void rotate(int count=1);
Packit df99a1
  /** Composes the affine transform with a symmetry with respect to the
Packit df99a1
      vertical line crossing the center of the output rectangle.  This
Packit df99a1
      operation essentially is a modification of the match between the corners
Packit df99a1
      of the input rectangle and the corners of the output rectangle. */
Packit df99a1
  void mirrorx();
Packit df99a1
  /** Composes the affine transform with a symmetry with respect to the
Packit df99a1
      horizontal line crossing the center of the output rectangle.  This
Packit df99a1
      operation essentially is a modification of the match between the corners
Packit df99a1
      of the input rectangle and the corners of the output rectangle. */
Packit df99a1
  void mirrory();
Packit df99a1
  /** Maps a point according to the affine transform.  Variables #x# and #y#
Packit df99a1
      initially contain the coordinates of a point. This operation overwrites
Packit df99a1
      these variables with the coordinates of a second point located in the
Packit df99a1
      same position relative to the corners of the output rectangle as the
Packit df99a1
      first point relative to the matching corners of the input rectangle.
Packit df99a1
      Coordinates are rounded to the nearest integer. */
Packit df99a1
  void map(int &x, int &y);
Packit df99a1
  /** Maps a rectangle according to the affine transform. This operation
Packit df99a1
      consists in mapping the rectangle corners and reordering the corners in
Packit df99a1
      the canonical rectangle representation.  Variable #rect# is overwritten
Packit df99a1
      with the new rectangle coordinates. */
Packit df99a1
  void map(GRect &rect);
Packit df99a1
  /** Maps a point according to the inverse of the affine transform.
Packit df99a1
      Variables #x# and #y# initially contain the coordinates of a point. This
Packit df99a1
      operation overwrites these variables with the coordinates of a second
Packit df99a1
      point located in the same position relative to the corners of input
Packit df99a1
      rectangle as the first point relative to the matching corners of the
Packit df99a1
      input rectangle. Coordinates are rounded to the nearest integer. */
Packit df99a1
  void unmap(int &x, int &y);
Packit df99a1
  /** Maps a rectangle according to the inverse of the affine transform. This
Packit df99a1
      operation consists in mapping the rectangle corners and reordering the
Packit df99a1
      corners in the canonical rectangle representation.  Variable #rect# is
Packit df99a1
      overwritten with the new rectangle coordinates. */
Packit df99a1
  void unmap(GRect &rect);
Packit df99a1
public:
Packit df99a1
  // GRatio
Packit df99a1
  struct GRatio {
Packit df99a1
    GRatio ();
Packit df99a1
    GRatio (int p, int q);
Packit df99a1
    int p;
Packit df99a1
    int q;
Packit df99a1
  };
Packit df99a1
private:
Packit df99a1
  // Data
Packit df99a1
  GRect rectFrom;
Packit df99a1
  GRect rectTo;
Packit df99a1
  int   code;
Packit df99a1
  // Helper
Packit df99a1
  void  precalc();
Packit df99a1
  friend int operator*(int n, GRatio r ); 
Packit df99a1
  friend int operator/(int n, GRatio r ); 
Packit df99a1
  GRatio rw;
Packit df99a1
  GRatio rh;
Packit df99a1
};
Packit df99a1
Packit df99a1
Packit df99a1
//@}
Packit df99a1
Packit df99a1
Packit df99a1
Packit df99a1
// ---- INLINES
Packit df99a1
Packit df99a1
inline
Packit df99a1
GRect::GRect()
Packit df99a1
: xmin(0), ymin(0), xmax(0), ymax(0)
Packit df99a1
{
Packit df99a1
}
Packit df99a1
Packit df99a1
inline 
Packit df99a1
GRect::GRect(int xmin, int ymin, unsigned int width, unsigned int height)
Packit df99a1
: xmin(xmin), ymin(ymin), xmax(xmin+width), ymax(ymin+height)
Packit df99a1
{
Packit df99a1
}
Packit df99a1
Packit df99a1
inline int 
Packit df99a1
GRect::width() const
Packit df99a1
{
Packit df99a1
  return xmax - xmin;
Packit df99a1
}
Packit df99a1
Packit df99a1
inline int 
Packit df99a1
GRect::height() const
Packit df99a1
{
Packit df99a1
  return ymax - ymin;
Packit df99a1
}
Packit df99a1
Packit df99a1
inline bool 
Packit df99a1
GRect::isempty() const
Packit df99a1
{
Packit df99a1
  return (xmin>=xmax || ymin>=ymax);
Packit df99a1
}
Packit df99a1
Packit df99a1
inline int 
Packit df99a1
GRect::area() const
Packit df99a1
{
Packit df99a1
  return isempty() ? 0 : (xmax-xmin)*(ymax-ymin);
Packit df99a1
}
Packit df99a1
Packit df99a1
inline int
Packit df99a1
GRect::contains(int x, int y) const
Packit df99a1
{
Packit df99a1
  return (x>=xmin && x<xmax && y>=ymin && y
Packit df99a1
}
Packit df99a1
  
Packit df99a1
inline void 
Packit df99a1
GRect::clear()
Packit df99a1
{
Packit df99a1
  xmin = xmax = ymin = ymax = 0;
Packit df99a1
}
Packit df99a1
Packit df99a1
inline int
Packit df99a1
operator!=(const GRect & r1, const GRect & r2)
Packit df99a1
{
Packit df99a1
   return !(r1==r2);
Packit df99a1
}
Packit df99a1
Packit df99a1
// ---- THE END
Packit df99a1
Packit df99a1
#ifdef HAVE_NAMESPACES
Packit df99a1
}
Packit df99a1
# ifndef NOT_USING_DJVU_NAMESPACE
Packit df99a1
using namespace DJVU;
Packit df99a1
# endif
Packit df99a1
#endif
Packit df99a1
#endif