App

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

- File List
- File Members

TCubicFInt.hpp
Go to the documentation of this file.
1
6 namespace app {
7 template<typename TPIXEL, typename TCHANNEL> class TCubicFInt;
8 }
9
10 #ifndef TCUBICFINT_HPP_
11 #define TCUBICFINT_HPP_
12
13 #include <cstdlib>
14 #include "../typedefs.hpp"
15 #include "../bitmaps/TBitmap.hpp"
16
17 #include "TFInterpolator.hpp"
18
20 #define INTERPOLATE_CUBIC(P0, P1, P2, P3, X, RES) \
21 RES = (-P0 + P3 + 3 * P1 - 3 * P2) * X * X * X / 0.2e1 + (-5 * P1 + 2 * P0 - P3 + 4 * P2) * X * X / 0.2e1 + (P2 - P0) * X / 0.2e1 + P1;
22
23 namespace app {
24
29 template<typename TPIXEL, typename TCHANNEL>
30 class TCubicFInt: public TFInterpolator<TPIXEL, TCHANNEL> {
31 protected:
32 TPIXEL * srcData;
33 unsigned srcWidth;
34 unsigned srcHeight;
35 int offset;
36
37 int * xReindex;
38 int * yReindex;
39 double xNoReindexFrom;
40 double xNoReindexTo;
41 double yNoReindexFrom;
42 double yNoReindexTo;
43
44 TPIXEL getAt_4ch(double x, double y) {
45 if (x > xNoReindexFrom && y > yNoReindexFrom && x < xNoReindexTo && y < yNoReindexTo) {
46 x -= 1.5;
47 y -= 1.5;
48 int X = x;
49 x -= X;
50 int Y = y;
51 y -= Y;
52
53 TPIXEL retVal = 0;
54 TCHANNEL * ptr = (TCHANNEL *) &retVal;
55 TCHANNEL * sBgn = (TCHANNEL *) (srcData + (Y) * srcWidth + (X));
56 TCHANNEL * sPtr;
57 TCHANNEL p0, p1, p2, p3;
58 double tp0, tp1, tp2, tp3;
59 double clamp;
60
61 sPtr = sBgn++;
62 p0 = *sPtr;
63 p1 = *(sPtr + 4);
64 p2 = *(sPtr + 8);
65 p3 = *(sPtr + 12);
66 sPtr += offset;
67 INTERPOLATE_CUBIC(p0, p1, p2, p3, x, tp0);
68 p0 = *sPtr;
69 p1 = *(sPtr + 4);
70 p2 = *(sPtr + 8);
71 p3 = *(sPtr + 12);
72 sPtr += offset;
73 INTERPOLATE_CUBIC(p0, p1, p2, p3, x, tp1);
74 p0 = *sPtr;
75 p1 = *(sPtr + 4);
76 p2 = *(sPtr + 8);
77 p3 = *(sPtr + 12);
78 sPtr += offset;
79 INTERPOLATE_CUBIC(p0, p1, p2, p3, x, tp2);
80 p0 = *sPtr;
81 p1 = *(sPtr + 4);
82 p2 = *(sPtr + 8);
83 p3 = *(sPtr + 12);
84 INTERPOLATE_CUBIC(p0, p1, p2, p3, x, tp3);
85 INTERPOLATE_CUBIC(tp0, tp1, tp2, tp3, y, clamp);
86 *ptr = (clamp > maxVal) ? maxVal : (clamp < 0) ? 0 : clamp;
87 ptr++;
88
89 sPtr = sBgn++;
90 p0 = *sPtr;
91 p1 = *(sPtr + 4);
92 p2 = *(sPtr + 8);
93 p3 = *(sPtr + 12);
94 sPtr += offset;
95 INTERPOLATE_CUBIC(p0, p1, p2, p3, x, tp0);
96 p0 = *sPtr;
97 p1 = *(sPtr + 4);
98 p2 = *(sPtr + 8);
99 p3 = *(sPtr + 12);
100 sPtr += offset;
101 INTERPOLATE_CUBIC(p0, p1, p2, p3, x, tp1);
102 p0 = *sPtr;
103 p1 = *(sPtr + 4);
104 p2 = *(sPtr + 8);
105 p3 = *(sPtr + 12);
106 sPtr += offset;
107 INTERPOLATE_CUBIC(p0, p1, p2, p3, x, tp2);
108 p0 = *sPtr;
109 p1 = *(sPtr + 4);
110 p2 = *(sPtr + 8);
111 p3 = *(sPtr + 12);
112 INTERPOLATE_CUBIC(p0, p1, p2, p3, x, tp3);
113 INTERPOLATE_CUBIC(tp0, tp1, tp2, tp3, y, clamp);
114 *ptr = (clamp > maxVal) ? maxVal : (clamp < 0) ? 0 : clamp;
115 ptr++;
116
117 sPtr = sBgn++;
118 p0 = *sPtr;
119 p1 = *(sPtr + 4);
120 p2 = *(sPtr + 8);
121 p3 = *(sPtr + 12);
122 sPtr += offset;
123 INTERPOLATE_CUBIC(p0, p1, p2, p3, x, tp0);
124 p0 = *sPtr;
125 p1 = *(sPtr + 4);
126 p2 = *(sPtr + 8);
127 p3 = *(sPtr + 12);
128 sPtr += offset;
129 INTERPOLATE_CUBIC(p0, p1, p2, p3, x, tp1);
130 p0 = *sPtr;
131 p1 = *(sPtr + 4);
132 p2 = *(sPtr + 8);
133 p3 = *(sPtr + 12);
134 sPtr += offset;
135 INTERPOLATE_CUBIC(p0, p1, p2, p3, x, tp2);
136 p0 = *sPtr;
137 p1 = *(sPtr + 4);
138 p2 = *(sPtr + 8);
139 p3 = *(sPtr + 12);
140 INTERPOLATE_CUBIC(p0, p1, p2, p3, x, tp3);
141 INTERPOLATE_CUBIC(tp0, tp1, tp2, tp3, y, clamp);
142 *ptr = (clamp > maxVal) ? maxVal : (clamp < 0) ? 0 : clamp;
143 ptr++;
144
145 sPtr = sBgn;
146 p0 = *sPtr;
147 p1 = *(sPtr + 4);
148 p2 = *(sPtr + 8);
149 p3 = *(sPtr + 12);
150 sPtr += offset;
151 INTERPOLATE_CUBIC(p0, p1, p2, p3, x, tp0);
152 p0 = *sPtr;
153 p1 = *(sPtr + 4);
154 p2 = *(sPtr + 8);
155 p3 = *(sPtr + 12);
156 sPtr += offset;
157 INTERPOLATE_CUBIC(p0, p1, p2, p3, x, tp1);
158 p0 = *sPtr;
159 p1 = *(sPtr + 4);
160 p2 = *(sPtr + 8);
161 p3 = *(sPtr + 12);
162 sPtr += offset;
163 INTERPOLATE_CUBIC(p0, p1, p2, p3, x, tp2);
164 p0 = *sPtr;
165 p1 = *(sPtr + 4);
166 p2 = *(sPtr + 8);
167 p3 = *(sPtr + 12);
168 INTERPOLATE_CUBIC(p0, p1, p2, p3, x, tp3);
169 INTERPOLATE_CUBIC(tp0, tp1, tp2, tp3, y, clamp);
170 *ptr = (clamp > maxVal) ? maxVal : (clamp < 0) ? 0 : clamp;
171
172 return retVal;
173
174 } else {
175 x += 1.5;
176 y += 1.5;
177 int X = x;
178 x -= X;
179 int Y = y;
180 y -= Y;
181
182 TPIXEL retVal = 0;
183 TCHANNEL * ptr = (TCHANNEL *) &retVal;
184 TCHANNEL p0, p1, p2, p3;
185
186 TCHANNEL * p00 = (TCHANNEL *) (srcData + yReindex[Y - 1] * srcWidth + xReindex[X - 1]);
187 TCHANNEL * p01 = (TCHANNEL *) (srcData + yReindex[Y] * srcWidth + xReindex[X - 1]);
188 TCHANNEL * p02 = (TCHANNEL *) (srcData + yReindex[Y + 1] * srcWidth + xReindex[X - 1]);
189 TCHANNEL * p03 = (TCHANNEL *) (srcData + yReindex[Y + 2] * srcWidth + xReindex[X - 1]);
190
191 TCHANNEL * p10 = (TCHANNEL *) (srcData + yReindex[Y - 1] * srcWidth + xReindex[X]);
192 TCHANNEL * p11 = (TCHANNEL *) (srcData + yReindex[Y] * srcWidth + xReindex[X]);
193 TCHANNEL * p12 = (TCHANNEL *) (srcData + yReindex[Y + 1] * srcWidth + xReindex[X]);
194 TCHANNEL * p13 = (TCHANNEL *) (srcData + yReindex[Y + 2] * srcWidth + xReindex[X]);
195
196 TCHANNEL * p20 = (TCHANNEL *) (srcData + yReindex[Y - 1] * srcWidth + xReindex[X + 1]);
197 TCHANNEL * p21 = (TCHANNEL *) (srcData + yReindex[Y] * srcWidth + xReindex[X + 1]);
198 TCHANNEL * p22 = (TCHANNEL *) (srcData + yReindex[Y + 1] * srcWidth + xReindex[X + 1]);
199 TCHANNEL * p23 = (TCHANNEL *) (srcData + yReindex[Y + 2] * srcWidth + xReindex[X + 1]);
200
201 TCHANNEL * p30 = (TCHANNEL *) (srcData + yReindex[Y - 1] * srcWidth + xReindex[X + 2]);
202 TCHANNEL * p31 = (TCHANNEL *) (srcData + yReindex[Y] * srcWidth + xReindex[X + 2]);
203 TCHANNEL * p32 = (TCHANNEL *) (srcData + yReindex[Y + 1] * srcWidth + xReindex[X + 2]);
204 TCHANNEL * p33 = (TCHANNEL *) (srcData + yReindex[Y + 2] * srcWidth + xReindex[X + 2]);
205
206 double tp0, tp1, tp2, tp3;
207 double clamp;
208
209 p0 = *(p00++);
210 p1 = *(p01++);
211 p2 = *(p02++);
212 p3 = *(p03++);
213 INTERPOLATE_CUBIC(p0, p1, p2, p3, x, tp0);
214 p0 = *(p10++);
215 p1 = *(p11++);
216 p2 = *(p12++);
217 p3 = *(p13++);
218 INTERPOLATE_CUBIC(p0, p1, p2, p3, x, tp1);
219 p0 = *(p20++);
220 p1 = *(p21++);
221 p2 = *(p22++);
222 p3 = *(p23++);
223 INTERPOLATE_CUBIC(p0, p1, p2, p3, x, tp2);
224 p0 = *(p30++);
225 p1 = *(p31++);
226 p2 = *(p32++);
227 p3 = *(p33++);
228 INTERPOLATE_CUBIC(p0, p1, p2, p3, x, tp3);
229 INTERPOLATE_CUBIC(tp0, tp1, tp2, tp3, y, clamp);
230 *ptr = (clamp > maxVal) ? maxVal : (clamp < 0) ? 0 : clamp;
231 ptr++;
232
233 p0 = *(p00++);
234 p1 = *(p01++);
235 p2 = *(p02++);
236 p3 = *(p03++);
237 INTERPOLATE_CUBIC(p0, p1, p2, p3, x, tp0);
238 p0 = *(p10++);
239 p1 = *(p11++);
240 p2 = *(p12++);
241 p3 = *(p13++);
242 INTERPOLATE_CUBIC(p0, p1, p2, p3, x, tp1);
243 p0 = *(p20++);
244 p1 = *(p21++);
245 p2 = *(p22++);
246 p3 = *(p23++);
247 INTERPOLATE_CUBIC(p0, p1, p2, p3, x, tp2);
248 p0 = *(p30++);
249 p1 = *(p31++);
250 p2 = *(p32++);
251 p3 = *(p33++);
252 INTERPOLATE_CUBIC(p0, p1, p2, p3, x, tp3);
253 INTERPOLATE_CUBIC(tp0, tp1, tp2, tp3, y, clamp);
254 *ptr = (clamp > maxVal) ? maxVal : (clamp < 0) ? 0 : clamp;
255 ptr++;
256
257 p0 = *(p00++);
258 p1 = *(p01++);
259 p2 = *(p02++);
260 p3 = *(p03++);
261 INTERPOLATE_CUBIC(p0, p1, p2, p3, x, tp0);
262 p0 = *(p10++);
263 p1 = *(p11++);
264 p2 = *(p12++);
265 p3 = *(p13++);
266 INTERPOLATE_CUBIC(p0, p1, p2, p3, x, tp1);
267 p0 = *(p20++);
268 p1 = *(p21++);
269 p2 = *(p22++);
270 p3 = *(p23++);
271 INTERPOLATE_CUBIC(p0, p1, p2, p3, x, tp2);
272 p0 = *(p30++);
273 p1 = *(p31++);
274 p2 = *(p32++);
275 p3 = *(p33++);
276 INTERPOLATE_CUBIC(p0, p1, p2, p3, x, tp3);
277 INTERPOLATE_CUBIC(tp0, tp1, tp2, tp3, y, clamp);
278 *ptr = (clamp > maxVal) ? maxVal : (clamp < 0) ? 0 : clamp;
279 ptr++;
280
281 p0 = *(p00);
282 p1 = *(p01);
283 p2 = *(p02);
284 p3 = *(p03);
285 INTERPOLATE_CUBIC(p0, p1, p2, p3, x, tp0);
286 p0 = *(p10);
287 p1 = *(p11);
288 p2 = *(p12);
289 p3 = *(p13);
290 INTERPOLATE_CUBIC(p0, p1, p2, p3, x, tp1);
291 p0 = *(p20);
292 p1 = *(p21);
293 p2 = *(p22);
294 p3 = *(p23);
295 INTERPOLATE_CUBIC(p0, p1, p2, p3, x, tp2);
296 p0 = *(p30);
297 p1 = *(p31);
298 p2 = *(p32);
299 p3 = *(p33);
300 INTERPOLATE_CUBIC(p0, p1, p2, p3, x, tp3);
301 INTERPOLATE_CUBIC(tp0, tp1, tp2, tp3, y, clamp);
302 *ptr = (clamp > maxVal) ? maxVal : (clamp < 0) ? 0 : clamp;
303
304 return retVal;
305 }
306 }
307
308 TPIXEL getAt_1ch(double x, double y) {
309 if (x > xNoReindexFrom && y > yNoReindexFrom && x < xNoReindexTo && y < yNoReindexTo) {
310 x -= 1.5;
311 y -= 1.5;
312 int X = x;
313 x -= X;
314 int Y = y;
315 y -= Y;
316
317 TPIXEL retVal = 0;
318 TPIXEL * sPtr = (srcData + (Y) * srcWidth + (X));
319 TPIXEL p0, p1, p2, p3;
320 double tp0, tp1, tp2, tp3;
321 double clamp;
322
323 p0 = *sPtr;
324 p1 = *(sPtr + 1);
325 p2 = *(sPtr + 2);
326 p3 = *(sPtr + 3);
327 sPtr += offset;
328 INTERPOLATE_CUBIC(p0, p1, p2, p3, x, tp0);
329 p0 = *sPtr;
330 p1 = *(sPtr + 1);
331 p2 = *(sPtr + 2);
332 p3 = *(sPtr + 3);
333 sPtr += offset;
334 INTERPOLATE_CUBIC(p0, p1, p2, p3, x, tp1);
335 p0 = *sPtr;
336 p1 = *(sPtr + 1);
337 p2 = *(sPtr + 2);
338 p3 = *(sPtr + 3);
339 sPtr += offset;
340 INTERPOLATE_CUBIC(p0, p1, p2, p3, x, tp2);
341 p0 = *sPtr;
342 p1 = *(sPtr + 1);
343 p2 = *(sPtr + 2);
344 p3 = *(sPtr + 3);
345 INTERPOLATE_CUBIC(p0, p1, p2, p3, x, tp3);
346 INTERPOLATE_CUBIC(tp0, tp1, tp2, tp3, y, clamp);
347 retVal = (clamp > maxVal) ? maxVal : (clamp < 0) ? 0 : clamp;
348
349 return retVal;
350
351 } else {
352 x += 1.5;
353 y += 1.5;
354 int X = x;
355 x -= X;
356 int Y = y;
357 y -= Y;
358
359 TPIXEL retVal = 0;
360 TPIXEL p0, p1, p2, p3;
361
362 TPIXEL * p00 = (srcData + yReindex[Y - 1] * srcWidth + xReindex[X - 1]);
363 TPIXEL * p01 = (srcData + yReindex[Y] * srcWidth + xReindex[X - 1]);
364 TPIXEL * p02 = (srcData + yReindex[Y + 1] * srcWidth + xReindex[X - 1]);
365 TPIXEL * p03 = (srcData + yReindex[Y + 2] * srcWidth + xReindex[X - 1]);
366
367 TPIXEL * p10 = (srcData + yReindex[Y - 1] * srcWidth + xReindex[X]);
368 TPIXEL * p11 = (srcData + yReindex[Y] * srcWidth + xReindex[X]);
369 TPIXEL * p12 = (srcData + yReindex[Y + 1] * srcWidth + xReindex[X]);
370 TPIXEL * p13 = (srcData + yReindex[Y + 2] * srcWidth + xReindex[X]);
371
372 TPIXEL * p20 = (srcData + yReindex[Y - 1] * srcWidth + xReindex[X + 1]);
373 TPIXEL * p21 = (srcData + yReindex[Y] * srcWidth + xReindex[X + 1]);
374 TPIXEL * p22 = (srcData + yReindex[Y + 1] * srcWidth + xReindex[X + 1]);
375 TPIXEL * p23 = (srcData + yReindex[Y + 2] * srcWidth + xReindex[X + 1]);
376
377 TPIXEL * p30 = (srcData + yReindex[Y - 1] * srcWidth + xReindex[X + 2]);
378 TPIXEL * p31 = (srcData + yReindex[Y] * srcWidth + xReindex[X + 2]);
379 TPIXEL * p32 = (srcData + yReindex[Y + 1] * srcWidth + xReindex[X + 2]);
380 TPIXEL * p33 = (srcData + yReindex[Y + 2] * srcWidth + xReindex[X + 2]);
381
382 double tp0, tp1, tp2, tp3;
383 double clamp;
384
385 p0 = *(p00);
386 p1 = *(p01);
387 p2 = *(p02);
388 p3 = *(p03);
389 INTERPOLATE_CUBIC(p0, p1, p2, p3, x, tp0);
390 p0 = *(p10);
391 p1 = *(p11);
392 p2 = *(p12);
393 p3 = *(p13);
394 INTERPOLATE_CUBIC(p0, p1, p2, p3, x, tp1);
395 p0 = *(p20);
396 p1 = *(p21);
397 p2 = *(p22);
398 p3 = *(p23);
399 INTERPOLATE_CUBIC(p0, p1, p2, p3, x, tp2);
400 p0 = *(p30);
401 p1 = *(p31);
402 p2 = *(p32);
403 p3 = *(p33);
404 INTERPOLATE_CUBIC(p0, p1, p2, p3, x, tp3);
405 INTERPOLATE_CUBIC(tp0, tp1, tp2, tp3, y, clamp);
406 retVal = (clamp > maxVal) ? maxVal : (clamp < 0) ? 0 : clamp;
407
408 return retVal;
409 }
410 }
411
417 virtual int resampleTo_4ch(TBitmap<TPIXEL, TCHANNEL> &dst) const;
418
419 // virtual int resampleTo_4ch_aliased(TBitmap<TPIXEL, TCHANNEL> &dst, double force) const;
420 // virtual int resampleTo_1ch_aliased(TBitmap<TPIXEL, TCHANNEL> &dst, double force) const;
421
427 virtual int resampleTo_1ch(TBitmap<TPIXEL, TCHANNEL> &dst) const;
428
429 virtual TFInterpolator<TPIXEL, TCHANNEL> * newInstance(const TBitmap<TPIXEL, TCHANNEL> &over) const {
430 return new TCubicFInt<TPIXEL, TCHANNEL>(over);
431 }
432
433 public:
434 static const unsigned chCount;
435 static const TCHANNEL maxVal;
436
437 TCubicFInt(const TBitmap<TPIXEL, TCHANNEL> &over) {
438 srcData = over.getData();
439 srcWidth = over.getWidth();
440 srcHeight = over.getHeight();
441 xNoReindexFrom = 1.5;
442 xNoReindexTo = srcWidth - 1.5;
443 yNoReindexFrom = 1.5;
444 yNoReindexTo = srcHeight - 1.5;
445 offset = (srcWidth) * (sizeof(TPIXEL) / sizeof(TCHANNEL));
446
447 int * ptr;
448 int * ptrEnd;
449 int i;
450 xReindex = (int *) malloc((unsigned long int) ((srcWidth + 4) * sizeof(int)));
451
452 ptr = xReindex;
453 ptrEnd = xReindex + srcWidth + 2;
454 *ptr = 0;
455 ptr++;
456 *ptr = 0;
457 ptr++;
458 i = 0;
459 while (ptr < ptrEnd) {
460 *ptr = i++;
461 ptr++;
462 }
463 *ptr = srcWidth - 1;
464 ptr++;
465 *ptr = srcWidth - 1;
466
467 yReindex = (int *) malloc((unsigned long int) ((srcHeight + 4) * sizeof(int)));
468 ptr = yReindex;
469 ptrEnd = yReindex + srcHeight + 2;
470 *ptr = 0;
471 ptr++;
472 *ptr = 0;
473 ptr++;
474 i = 0;
475 while (ptr < ptrEnd) {
476 *ptr = i++;
477 ptr++;
478 }
479 *ptr = srcHeight - 1;
480 ptr++;
481 *ptr = srcHeight - 1;
482
483 }
484
485 virtual int isInitOk() const {
486 if (xReindex != NULL && yReindex != NULL) {
487 return 1;
488 } else {
489 return 0;
490 }
491 }
492
493 virtual TPIXEL * getSrcData() const {
494 return srcData;
495 }
496
497 virtual unsigned getSrcWidth() const {
498 return srcWidth;
499 }
500 virtual unsigned getSrcHeight() const {
501 return srcHeight;
502 }
503
504 virtual ~TCubicFInt();
505
506 TPIXEL getAt(double x, double y) {
507 if (x <= 0 || y <= 0 || x >= srcWidth || y >= srcHeight) {
508 return 0;
509 } else if (chCount == 4) {
510 return getAt_4ch(x, y);
511 } else if (chCount == 1) {
512 return getAt_1ch(x, y);
513 } else {
514 return 0; // Jen kvůli warningu
515 }
516 }
517 };
518
519 template<typename TPIXEL, typename TCHANNEL>
520 const unsigned TCubicFInt<TPIXEL, TCHANNEL>::chCount = sizeof(TPIXEL) / sizeof(TCHANNEL);
521
522 template<typename TPIXEL, typename TCHANNEL>
523 const TCHANNEL TCubicFInt<TPIXEL, TCHANNEL>::maxVal = ~0;
524
525 }
526 #endif