RAWK
Gigapixel Raw Image Processing Toolkit
 All Classes Functions Variables Pages
image_resample.hpp
1 // RAWK Copyright (C) 2014 Robert Kooima
2 //
3 // This program is free software: you can redistribute it and/or modify it
4 // under the terms of the GNU General Public License as published by the Free
5 // Software Foundation, either version 3 of the License, or (at your option)
6 // any later version.
7 //
8 // This program is distributed in the hope that it will be useful, but WITH-
9 // OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 // more details.
12 
13 #ifndef IMAGE_RESAMPLE_HPP
14 #define IMAGE_RESAMPLE_HPP
15 
16 //------------------------------------------------------------------------------
17 
19 
20 static inline double lerp(double a, double b, double t)
21 {
22  return b * t + a * (1 - t);
23 }
24 
26 
27 static inline double cerp(double a, double b, double c, double d, double t)
28 {
29  return b + (-a / 2 + c / 2 ) * t
30  + ( a - 5 * b / 2 + 2 * c - d / 2) * t * t
31  + (-a / 2 + 3 * b / 2 - 3 * c / 2 + d / 2) * t * t * t;
32 }
33 
34 //------------------------------------------------------------------------------
35 
37 
38 class resample : public image
39 {
40 public:
41  resample(int height, int width, int mode, image *L)
42  : image(L), height(height), width(width), mode(mode) { }
43 
44  virtual int get_height() const { return height; }
45  virtual int get_width () const { return width; }
46 
47  virtual void tweak(int a, int v)
48  {
49  if (a == 0) width -= v;
50  if (a == 1) height -= v;
51  }
52 
53 protected:
54  int height;
55  int width;
56  int mode;
57 };
58 
59 //------------------------------------------------------------------------------
60 
62 
63 class nearest : public resample
64 {
65 public:
68 
69  nearest(int height, int width, image *L) : resample(height, width, 0, L) { }
70 
71  virtual double get(int i, int j, int k) const
72  {
73  const long long hh = (long long) L->get_height();
74  const long long ww = (long long) L->get_width();
75 
76  return L->get(int((long long) i * hh / (long long) height),
77  int((long long) j * ww / (long long) width), k);
78  }
79 
80  virtual void doc(std::ostream& out) const
81  {
82  out << "nearest " << height << " " << width;
83  }
84 };
85 
86 //------------------------------------------------------------------------------
87 
89 
90 class linear : public resample
91 {
92 public:
95 
96  linear(int height, int width, int mode, image *L)
97  : resample(height, width, mode, L) { }
98 
99  virtual double get(int i, int j, int k) const
100  {
101  int hh = L->get_height();
102  int ww = L->get_width();
103 
104  double ii = double(i) * double(hh) / double(height);
105  double jj = double(j) * double(ww) / double(width);
106 
107  double s = ii - floor(ii);
108  double t = jj - floor(jj);
109 
110  int ia = wrap(int(floor(ii)), hh, mode & 1);
111  int ib = wrap(int( ceil(ii)), hh, mode & 1);
112  int ja = wrap(int(floor(jj)), ww, mode & 2);
113  int jb = wrap(int( ceil(jj)), ww, mode & 2);
114 
115  double aa = L->get(ia, ja, k);
116  double ab = L->get(ia, jb, k);
117  double ba = L->get(ib, ja, k);
118  double bb = L->get(ib, jb, k);
119 
120  return lerp(lerp(aa, ab, t),
121  lerp(ba, bb, t), s);
122  }
123 
124  virtual void doc(std::ostream& out) const
125  {
126  out << "linear " << height << " " << width << " " << mode;
127  }
128 };
129 
130 //------------------------------------------------------------------------------
131 
133 
134 class cubic : public resample
135 {
136 public:
139 
140  cubic(int height, int width, int mode, image *L)
141  : resample(height, width, mode, L) { }
142 
143  virtual double get(int i, int j, int k) const
144  {
145  int hh = L->get_height();
146  int ww = L->get_width();
147 
148  double ii = double(i) * double(hh) / double(height);
149  double jj = double(j) * double(ww) / double(width);
150 
151  double s = ii - floor(ii);
152  double t = jj - floor(jj);
153 
154  int ib = wrap(int(floor(ii)), hh, mode & 1);
155  int ic = wrap(int( ceil(ii)), hh, mode & 1);
156  int jb = wrap(int(floor(jj)), ww, mode & 2);
157  int jc = wrap(int( ceil(jj)), ww, mode & 2);
158 
159  int ia = wrap(ib - 1, hh, mode & 1);
160  int id = wrap(ic + 1, hh, mode & 1);
161  int ja = wrap(jb - 1, ww, mode & 2);
162  int jd = wrap(jc + 1, ww, mode & 2);
163 
164  double aa = L->get(ia, ja, k);
165  double ab = L->get(ia, jb, k);
166  double ac = L->get(ia, jc, k);
167  double ad = L->get(ia, jd, k);
168  double ba = L->get(ib, ja, k);
169  double bb = L->get(ib, jb, k);
170  double bc = L->get(ib, jc, k);
171  double bd = L->get(ib, jd, k);
172  double ca = L->get(ic, ja, k);
173  double cb = L->get(ic, jb, k);
174  double cc = L->get(ic, jc, k);
175  double cd = L->get(ic, jd, k);
176  double da = L->get(id, ja, k);
177  double db = L->get(id, jb, k);
178  double dc = L->get(id, jc, k);
179  double dd = L->get(id, jd, k);
180 
181  return cerp(cerp(aa, ab, ac, ad, t),
182  cerp(ba, bb, bc, bd, t),
183  cerp(ca, cb, cc, cd, t),
184  cerp(da, db, dc, dd, t), s);
185  }
186 
187  virtual void doc(std::ostream& out) const
188  {
189  out << "cubic " << height << " " << width << " " << mode;
190  }
191 };
192 
193 //------------------------------------------------------------------------------
194 
195 #endif
Resampling filter base class.
Definition: image_resample.hpp:38
virtual double get(int i, int j, int k) const =0
Return the value of the sample at row i, column j, channel k.
image * L
Left child.
Definition: image.hpp:117
image(image *L=0, image *R=0)
Create a new image object with left child L and right child R. The parents of L and R are set to this...
Definition: image.hpp:26
cubic(int height, int width, int mode, image *L)
Resample L to the given height and width using cubic-interpolated sampling. Mode gives the wrap mode...
Definition: image_resample.hpp:140
Base class for all image sources, filters, and operators.
Definition: image.hpp:20
Cubic-interpolated resampling filter.
Definition: image_resample.hpp:134
virtual int get_height() const
Return the height of this image.
Definition: image.hpp:46
virtual int get_width() const
Return the height of this image.
Definition: image_resample.hpp:45
nearest(int height, int width, image *L)
Resample L to the given height and width using nearest-neighbor sampling. The wrap mode for neast sam...
Definition: image_resample.hpp:69
virtual int get_height() const
Return the height of this image.
Definition: image_resample.hpp:44
virtual int get_width() const
Return the height of this image.
Definition: image.hpp:56
Linearly-interpolated resampling filter.
Definition: image_resample.hpp:90
virtual void doc(std::ostream &out) const
Produce a string documenting the function of this object.
Definition: image_resample.hpp:187
virtual void doc(std::ostream &out) const
Produce a string documenting the function of this object.
Definition: image_resample.hpp:80
virtual void doc(std::ostream &out) const
Produce a string documenting the function of this object.
Definition: image_resample.hpp:124
linear(int height, int width, int mode, image *L)
Resample L to the given height and width using linearly- interpolated sampling. Mode gives the wrap m...
Definition: image_resample.hpp:96
virtual void tweak(int a, int v)
Tweak image parameter a, changing the value by a factor of v.
Definition: image_resample.hpp:47
Nearest value resampling filter.
Definition: image_resample.hpp:63