App

- Main Page
- Related Pages
- Namespaces
- Classes
- Files

- File List
- File Members

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;
38 double xNoReindexFrom;
39 double xNoReindexTo;
40 double yNoReindexFrom;
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
209 virtual TFInterpolator<TPIXEL, TCHANNEL> * newInstance(const TBitmap<TPIXEL, TCHANNEL> &over) const {
210 return new TLinearFInt<TPIXEL, TCHANNEL>(over);
211 }
212
213 public:
214 static const unsigned chCount;
215 static const TCHANNEL maxVal;
216
217 TLinearFInt(const TBitmap<TPIXEL, TCHANNEL> &over) {
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