App
TLinearFInt.hpp
Go to the documentation of this file.
1 
6 namespace app {
7 template<typename TPIXEL, typename TCHANNEL> class TLinearFInt;
8 }
9 
10 #ifndef TLINEARFINT_HPP_
11 #define TLINEARFINT_HPP_
12 
13 #include <cstdlib>
14 #include "../typedefs.hpp"
15 #include "../bitmaps/TBitmap.hpp"
16 
17 #include "TFInterpolator.hpp"
18 
20 #define INTERPOLATE_BILINEAR(P11, P12, P21, P22, X, Y, RES) \
21  RES = ((-P12 + P11 - P21 + P22) * Y - P11 + P21) * X + (-P11 + P12) * Y + P11;
22 
23 #define INTERPOLATE_LINEAR(P1, P2, X, RES) \
24  RES = P1 + (P2 - P1) * X;
25 
26 namespace app {
27 
28 template<typename TPIXEL, typename TCHANNEL>
29 class TLinearFInt: public TFInterpolator<TPIXEL, TCHANNEL> {
30 protected:
31  TPIXEL * srcData;
32  unsigned srcWidth;
33  unsigned srcHeight;
34 
35  int * xReindex; // Zbytecna alokace velkeho pole, ale rezise se ztrati...
36  int * yReindex;
37  int offset;
39  double xNoReindexTo;
41  double yNoReindexTo;
42 
46  TPIXEL getAt_4ch(double x, double y) {
47  if (x > xNoReindexFrom && y > yNoReindexFrom && x < xNoReindexTo && y < yNoReindexTo) {
48  x -= 0.5;
49  y -= 0.5;
50  int X = x;
51  x -= X;
52  int Y = y;
53  y -= Y;
54 
55  TPIXEL retVal = 0;
56  TCHANNEL * ptr = (TCHANNEL *) &retVal;
57  TCHANNEL * px11 = (TCHANNEL *) (srcData + (Y) * srcWidth + (X));
58  TCHANNEL * px21 = px11 + 4;
59  TCHANNEL * px12 = px11 + offset;
60  TCHANNEL * px22 = px12 + 4;
61 
62  TCHANNEL p11, p12, p21, p22;
63 
64  p11 = *(px11++);
65  p12 = *(px12++);
66  p21 = *(px21++);
67  p22 = *(px22++);
68  INTERPOLATE_BILINEAR(p11, p12, p21, p22, x, y, *ptr)
69  ptr++;
70 
71  p11 = *(px11++);
72  p12 = *(px12++);
73  p21 = *(px21++);
74  p22 = *(px22++);
75  INTERPOLATE_BILINEAR(p11, p12, p21, p22, x, y, *ptr)
76  ptr++;
77 
78  p11 = *(px11++);
79  p12 = *(px12++);
80  p21 = *(px21++);
81  p22 = *(px22++);
82  INTERPOLATE_BILINEAR(p11, p12, p21, p22, x, y, *ptr)
83  ptr++;
84 
85  p11 = *(px11);
86  p12 = *(px12);
87  p21 = *(px21);
88  p22 = *(px22);
89  INTERPOLATE_BILINEAR(p11, p12, p21, p22, x, y, *ptr)
90 
91  return retVal;
92 
93  } else {
94  x -= 0.5;
95  y -= 0.5;
96  int X = x;
97  x -= X;
98  int Y = y;
99  y -= Y;
100 
101  TPIXEL retVal = 0;
102  TCHANNEL * ptr = (TCHANNEL *) &retVal;
103  TCHANNEL * px11 = (TCHANNEL *) (srcData + yReindex[Y] * srcWidth + xReindex[X]);
104  TCHANNEL * px21 = (TCHANNEL *) (srcData + yReindex[Y] * srcWidth + xReindex[X + 1]);
105  TCHANNEL * px12 = (TCHANNEL *) (srcData + yReindex[Y + 1] * srcWidth + xReindex[X]);
106  TCHANNEL * px22 = (TCHANNEL *) (srcData + yReindex[Y + 1] * srcWidth + xReindex[X + 1]);
107 
108  TCHANNEL p11, p12, p21, p22;
109 
110  p11 = *(px11++);
111  p12 = *(px12++);
112  p21 = *(px21++);
113  p22 = *(px22++);
114  INTERPOLATE_BILINEAR(p11, p12, p21, p22, x, y, *ptr)
115  ptr++;
116 
117  p11 = *(px11++);
118  p12 = *(px12++);
119  p21 = *(px21++);
120  p22 = *(px22++);
121  INTERPOLATE_BILINEAR(p11, p12, p21, p22, x, y, *ptr)
122  ptr++;
123 
124  p11 = *(px11++);
125  p12 = *(px12++);
126  p21 = *(px21++);
127  p22 = *(px22++);
128  INTERPOLATE_BILINEAR(p11, p12, p21, p22, x, y, *ptr)
129  ptr++;
130 
131  p11 = *(px11);
132  p12 = *(px12);
133  p21 = *(px21);
134  p22 = *(px22);
135  INTERPOLATE_BILINEAR(p11, p12, p21, p22, x, y, *ptr)
136 
137  return retVal;
138  }
139  }
140 
144  TPIXEL getAt_1ch(double x, double y) {
145  if (x > xNoReindexFrom && y > yNoReindexFrom && x < xNoReindexTo && y < yNoReindexTo) {
146  x -= 0.5;
147  y -= 0.5;
148  int X = x;
149  x -= X;
150  int Y = y;
151  y -= Y;
152 
153  TPIXEL retVal = 0;
154  TPIXEL * px11 = (srcData + (Y) * srcWidth + (X));
155  TPIXEL * px21 = px11 + 1;
156  TPIXEL * px12 = px11 + srcWidth;
157  TPIXEL * px22 = px12 + 1;
158 
159  TPIXEL p11, p12, p21, p22;
160 
161  p11 = *(px11);
162  p12 = *(px12);
163  p21 = *(px21);
164  p22 = *(px22);
165  INTERPOLATE_BILINEAR(p11, p12, p21, p22, x, y, retVal)
166 
167  return retVal;
168 
169  } else {
170  x += 0.5;
171  y += 0.5;
172  int X = x;
173  x -= X;
174  int Y = y;
175  y -= Y;
176 
177  TPIXEL retVal = 0;
178  TPIXEL * px11 = (srcData + yReindex[Y] * srcWidth + xReindex[X]);
179  TPIXEL * px21 = (srcData + yReindex[Y] * srcWidth + xReindex[X + 1]);
180  TPIXEL * px12 = (srcData + yReindex[Y + 1] * srcWidth + xReindex[X]);
181  TPIXEL * px22 = (srcData + yReindex[Y + 1] * srcWidth + xReindex[X + 1]);
182 
183  px_1x8bit p11, p12, p21, p22;
184 
185  p11 = *(px11);
186  p12 = *(px12);
187  p21 = *(px21);
188  p22 = *(px22);
189  INTERPOLATE_BILINEAR(p11, p12, p21, p22, x, y, retVal)
190 
191  return retVal;
192  }
193  }
194 
200  virtual int resampleTo_4ch(TBitmap<TPIXEL, TCHANNEL> &dst) const;
201 
207  virtual int resampleTo_1ch(TBitmap<TPIXEL, TCHANNEL> &dst) const;
208 
210  return new TLinearFInt<TPIXEL, TCHANNEL>(over);
211  }
212 
213 public:
214  static const unsigned chCount;
215  static const TCHANNEL maxVal;
216 
218  srcData = over.getData();
219  srcWidth = over.getWidth();
220  srcHeight = over.getHeight();
221  xNoReindexFrom = 0.5;
222  xNoReindexTo = srcWidth - 0.5;
223  yNoReindexFrom = 0.5;
224  yNoReindexTo = srcHeight - 0.5;
225 
226  offset = srcWidth * chCount;
227 
228  int * ptr;
229  int * ptrEnd;
230  int i;
231  xReindex = (int *) malloc((unsigned long int) ((srcWidth + 2) * sizeof(int)));
232 
233  ptr = xReindex;
234  ptrEnd = xReindex + srcWidth + 1;
235  *ptr = 0;
236  ptr++;
237  i = 0;
238  while (ptr < ptrEnd) {
239  *ptr = i++;
240  ptr++;
241  }
242  *ptr = srcWidth - 1;
243 
244  yReindex = (int *) malloc((unsigned long int) ((srcHeight + 2) * sizeof(int)));
245  ptr = yReindex;
246  ptrEnd = yReindex + srcHeight + 1;
247  *ptr = 0;
248  ptr++;
249  i = 0;
250  while (ptr < ptrEnd) {
251  *ptr = i++;
252  ptr++;
253  }
254  *ptr = srcHeight - 1;
255 
256  }
257 
258  virtual int isInitOk() const {
259  if (xReindex != NULL && yReindex != NULL) {
260  return 1;
261  } else {
262  return 0;
263  }
264  }
265 
266  virtual ~TLinearFInt();
267 
268  TPIXEL getAt(double x, double y) {
269  if (x <= 0 || y <= 0 || x >= srcWidth || y >= srcHeight) {
270  return 0;
271  } else if (chCount == 4) {
272  return getAt_4ch(x, y);
273  } else if (chCount == 1) {
274  return getAt_1ch(x, y);
275  } else {
276  return 0; // Jen kvůli warningu
277  }
278  }
279 
280  virtual TPIXEL * getSrcData() const {
281  return srcData;
282  }
283 
284  virtual unsigned getSrcWidth() const {
285  return srcWidth;
286  }
287  virtual unsigned getSrcHeight() const {
288  return srcHeight;
289  }
290 
291 };
292 
293 template<typename TPIXEL, typename TCHANNEL>
294 const unsigned TLinearFInt<TPIXEL, TCHANNEL>::chCount = sizeof(TPIXEL) / sizeof(TCHANNEL);
295 
296 template<typename TPIXEL, typename TCHANNEL>
297 const TCHANNEL TLinearFInt<TPIXEL, TCHANNEL>::maxVal = ~0;
298 
299 }
300 #endif