VideoTools
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
grscaler.h
Go to the documentation of this file.
1 //
2 // Copyright (C) 2017 Graeme Walker
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
16 // ===
17 ///
18 /// \file grscaler.h
19 ///
20 
21 #ifndef GR_SCALER__H
22 #define GR_SCALER__H
23 
24 #include "gdef.h"
25 
26 namespace Gr
27 {
28  class ScalerImp ;
29  class Scaler ;
30 }
31 
32 /// \class Gr::ScalerImp
33 /// A base class for Gr::Scaler that does scaling using the Bresenham
34 /// algorithm, but limited to the first quadrant.
35 ///
37 {
38 public:
39  ScalerImp( int dfirst , int dsecond ) ;
40  ///< Constructor for iterating over the first range. The first dimension is
41  ///< 'fast' since it increases on each iteration, and the second is 'slow'
42  ///< since it increases conditionally.
43  ///< Precondition: dfirst >= dsecond
44 
45  operator bool() const ;
46  ///< Returns true if the current iteration position is still in range.
47 
48  bool operator!() const ;
49  ///< Returns false if the current iteration position is still in range.
50 
51  int a() const ;
52  ///< Returns the current value in the first range.
53 
54  int b() const ;
55  ///< Returns the calculated value in the second range.
56 
57  void operator++() ;
58  ///< Moves on to the next position in the first range.
59 
60 private:
61  int dfast ;
62  int dslow ;
63  int fast ;
64  int slow ;
65  int e ;
66 } ;
67 
68 /// \class Gr::Scaler
69 /// A class that allows for iterating over one integer range while accessing values
70 /// from another, with no requirement for one range to be a multiple of the other,
71 /// eg. for image scaling:
72 /// \code
73 ///
74 /// for( Scaler y_scaler(display.dy(),image.dy()) ; !!y_scaler ; ++y_scaler )
75 /// {
76 /// for( Scaler x_scaler(display.dx(),image.dx()) ; !!x_scaler ; ++x_scaler )
77 /// {
78 /// int display_x = x_scaler.first() ;
79 /// int display_y = y_scaler.first() ;
80 /// int image_x = x_scaler.second() ;
81 /// int image_y = y_scaler.second() ;
82 /// ...
83 /// }
84 /// }
85 /// \endcode
86 ///
87 /// Note that the iteration methods are in the base class.
88 ///
89 class Gr::Scaler : public Gr::ScalerImp
90 {
91 public:
92  Scaler( int dfirst , int dsecond ) ;
93  ///< Constructor for iterating over the first range while calculating
94  ///< scaled values in the second.
95 
96  int first() const ;
97  ///< Returns the current value in the first range.
98  ///< Postcondition: first() >= 0 && first() < dfirst
99 
100  int second() const ;
101  ///< Returns the corresponding value in the second range.
102  ///< Postcondition: second() >= 0 && second() < dsecond
103 
104 private:
105  bool swap ;
106 } ;
107 
108 inline Gr::ScalerImp::ScalerImp( int dfirst , int dsecond ) : dfast(dfirst) , dslow(dsecond) , fast(0) , slow(0) , e(2*dslow-dfast) {}
109 inline Gr::ScalerImp::operator bool() const { return fast < dfast ; }
110 inline bool Gr::ScalerImp::operator!() const { return fast >= dfast ; }
111 inline int Gr::ScalerImp::a() const { return fast ; }
112 inline int Gr::ScalerImp::b() const { return slow ; }
113 inline void Gr::ScalerImp::operator++() { fast++ ; if( e >= 0 ) { if((slow+1)<dslow) slow++ ; e -= dfast ; } e += dslow ; }
114 
115 inline Gr::Scaler::Scaler( int dfirst , int dsecond ) : ScalerImp(dfirst>dsecond?dfirst:dsecond,dfirst>dsecond?dsecond:dfirst) , swap(!(dfirst>dsecond)) {}
116 inline int Gr::Scaler::first() const { return swap ? ScalerImp::b() : ScalerImp::a() ; }
117 inline int Gr::Scaler::second() const { return swap ? ScalerImp::a() : ScalerImp::b() ; }
118 
119 #endif
int first() const
Returns the current value in the first range.
Definition: grscaler.h:116
bool operator!() const
Returns false if the current iteration position is still in range.
Definition: grscaler.h:110
A class that allows for iterating over one integer range while accessing values from another...
Definition: grscaler.h:89
int b() const
Returns the calculated value in the second range.
Definition: grscaler.h:112
Scaler(int dfirst, int dsecond)
Constructor for iterating over the first range while calculating scaled values in the second...
Definition: grscaler.h:115
ScalerImp(int dfirst, int dsecond)
Constructor for iterating over the first range.
Definition: grscaler.h:108
int a() const
Returns the current value in the first range.
Definition: grscaler.h:111
void operator++()
Moves on to the next position in the first range.
Definition: grscaler.h:113
int second() const
Returns the corresponding value in the second range.
Definition: grscaler.h:117
A base class for Gr::Scaler that does scaling using the Bresenham algorithm, but limited to the first...
Definition: grscaler.h:36