App

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

- File List
- File Members

TLinearFilter.cpp
Go to the documentation of this file.
1
6 #include "TLinearFilter.hpp"
7
8 #define LINEAR_FILTER_ALGORITHM_GENERAL(PX_INIT, KERNEL_ACTION, PX_COMMIT, PX_INCREMENT, ROW_INCREMENT) \
9 /* Parametry filtru */\
10 const int xKernelCenter = this->kernelWCenter;\
11 const int yKernelCenter = this->kernelHCenter;\
12 \
13 double * kernelPtr;\
14 double * kernelPtrRowEnd;\
15 double * const kernelFirstRowEnd = kernel + kernelWidth;\
16 double * const kernelEnd = kernel + kernelWidth * kernelHeight;\
17 \
18 TPIXEL * sPtr;\
19 \
20 int tmp;\
21 tmp = (yNoReindexFrom < yMax) ? yNoReindexFrom : yMax;\
22 TPIXEL * dPtrInitReindexVerticalLimit = dst + tmp * width;\
23 tmp = (yNoReindexTo < yMax) ? yNoReindexTo : yMax;\
24 TPIXEL * dPtrNoReindexVerticalLimit = dst + tmp * width;\
25 tmp = (height < yMax) ? height : yMax;\
26 TPIXEL * dPtrVerticalLimit = dst + width * tmp;\
27 \
28 tmp = (xNoReindexFrom < xMax) ? xNoReindexFrom : xMax;\
29 TPIXEL * dPtrInitReindexHorizontalLimit = dst + yMin * width + tmp;\
30 tmp = (xNoReindexTo < xMax) ? xNoReindexTo : xMax;\
31 TPIXEL * dPtrNoReindexHorizontalLimit = dst + yMin * width + tmp;\
32 tmp = (width < xMax) ? width : xMax;\
33 TPIXEL * dPtrHorizontalLimit = dst + yMin * width + tmp;\
34 \
35 TCHANNEL maxVal = this->maxVal;\
36 \
37 int x, y;\
38 int xStart, xStartStart, yStart;\
39 \
40 yStart = yMin - yKernelCenter;\
41 xStartStart = xMin - xKernelCenter;\
42 while (dPtr < dPtrInitReindexVerticalLimit) {\
43 \
44 /* TL roh */\
45 xStart = xStartStart;\
46 while (dPtr < dPtrInitReindexHorizontalLimit) {\
47 PX_INIT\
48 kernelPtr = kernel;\
49 kernelPtrRowEnd = kernelFirstRowEnd;\
50 y = yStart;\
51 \
52 while (kernelPtr < kernelEnd) {\
53 x = xStart;\
54 while (kernelPtr < kernelPtrRowEnd) {\
55 sPtr = src + yLo->reindex(y) * width + xLo->reindex(x);\
56 KERNEL_ACTION\
57 kernelPtr++;\
58 x++;\
59 }\
60 kernelPtrRowEnd += kernelWidth;\
61 y++;\
62 }\
63 PX_COMMIT\
64 xStart++;\
65 PX_INCREMENT\
66 }\
67 \
68 /* T hrana */\
69 while (dPtr < dPtrNoReindexHorizontalLimit) {\
70 PX_INIT\
71 kernelPtr = kernel;\
72 kernelPtrRowEnd = kernelFirstRowEnd;\
73 y = yStart;\
74 while (kernelPtr < kernelEnd) {\
75 sPtr = src + yLo->reindex(y) * width + xStart;\
76 while (kernelPtr < kernelPtrRowEnd) {\
77 KERNEL_ACTION\
78 kernelPtr++;\
79 sPtr++;\
80 }\
81 kernelPtrRowEnd += kernelWidth;\
82 y++;\
83 }\
84 PX_COMMIT\
85 xStart++;\
86 PX_INCREMENT\
87 }\
88 \
89 /* TR roh */\
90 while (dPtr < dPtrHorizontalLimit) {\
91 PX_INIT\
92 kernelPtr = kernel;\
93 kernelPtrRowEnd = kernelFirstRowEnd;\
94 y = yStart;\
95 while (kernelPtr < kernelEnd) {\
96 x = xStart;\
97 while (kernelPtr < kernelPtrRowEnd) {\
98 sPtr = src + yLo->reindex(y) * width + xHi->reindex(x);\
99 KERNEL_ACTION\
100 kernelPtr++;\
101 x++;\
102 }\
103 kernelPtrRowEnd += kernelWidth;\
104 y++;\
105 }\
106 PX_COMMIT\
107 xStart++;\
108 PX_INCREMENT\
109 }\
110 \
111 dPtrInitReindexHorizontalLimit += width;\
112 dPtrNoReindexHorizontalLimit += width;\
113 dPtrHorizontalLimit += width;\
114 \
115 yStart++;\
116 \
117 ROW_INCREMENT\
118 \
119 }\
120 \
121 TPIXEL * sPtrRowBgn = src + yStart * width;\
122 TPIXEL * sPtrBgn;\
123 \
124 int sPtrRowOffset = width - kernelWidth;\
125 \
126 while (dPtr < dPtrNoReindexVerticalLimit) {\
127 \
128 /* L Hrana */\
129 xStart = xStartStart;\
130 while (dPtr < dPtrInitReindexHorizontalLimit) {\
131 PX_INIT\
132 kernelPtr = kernel;\
133 kernelPtrRowEnd = kernelFirstRowEnd;\
134 sPtrBgn = sPtrRowBgn;\
135 while (kernelPtr < kernelEnd) {\
136 x = xStart;\
137 while (kernelPtr < kernelPtrRowEnd) {\
138 sPtr = sPtrBgn + xLo->reindex(x);\
139 KERNEL_ACTION\
140 kernelPtr++;\
141 x++;\
142 }\
143 sPtrBgn += width;\
144 kernelPtrRowEnd += kernelWidth;\
145 }\
146 PX_COMMIT\
147 xStart++;\
148 PX_INCREMENT\
149 }\
150 \
151 /* stred */\
152 sPtrBgn = sPtrRowBgn + xStart;\
153 while (dPtr < dPtrNoReindexHorizontalLimit) {\
154 PX_INIT\
155 kernelPtr = kernel;\
156 kernelPtrRowEnd = kernelFirstRowEnd;\
157 sPtr = sPtrBgn++;\
158 while (kernelPtr < kernelEnd) {\
159 while (kernelPtr < kernelPtrRowEnd) {\
160 KERNEL_ACTION\
161 sPtr++;\
162 kernelPtr++;\
163 }\
164 kernelPtrRowEnd += kernelWidth;\
165 sPtr += sPtrRowOffset;\
166 }\
167 PX_COMMIT\
168 PX_INCREMENT\
169 }\
170 \
171 /* R hrana */\
172 xStart = xNoReindexTo - xKernelCenter;\
173 while (dPtr < dPtrHorizontalLimit) {\
174 PX_INIT\
175 kernelPtr = kernel;\
176 kernelPtrRowEnd = kernelFirstRowEnd;\
177 sPtrBgn = sPtrRowBgn;\
178 while (kernelPtr < kernelEnd) {\
179 x = xStart;\
180 while (kernelPtr < kernelPtrRowEnd) {\
181 sPtr = sPtrBgn + xHi->reindex(x);\
182 KERNEL_ACTION\
183 kernelPtr++;\
184 x++;\
185 }\
186 sPtrBgn += width;\
187 kernelPtrRowEnd += kernelWidth;\
188 }\
189 PX_COMMIT\
190 xStart++;\
191 PX_INCREMENT\
192 }\
193 \
194 dPtrInitReindexHorizontalLimit += width;\
195 dPtrNoReindexHorizontalLimit += width;\
196 dPtrHorizontalLimit += width;\
197 \
198 sPtrRowBgn += width;\
199 \
200 ROW_INCREMENT\
201 }\
202 \
203 yStart = yNoReindexTo - yKernelCenter;\
204 while (dPtr < dPtrVerticalLimit) {\
205 \
206 /* BL roh */\
207 xStart = xStartStart;\
208 while (dPtr < dPtrInitReindexHorizontalLimit) {\
209 PX_INIT\
210 kernelPtr = kernel;\
211 kernelPtrRowEnd = kernelFirstRowEnd;\
212 y = yStart;\
213 \
214 while (kernelPtr < kernelEnd) {\
215 x = xStart;\
216 while (kernelPtr < kernelPtrRowEnd) {\
217 sPtr = src + yHi->reindex(y) * width + xLo->reindex(x);\
218 KERNEL_ACTION\
219 kernelPtr++;\
220 x++;\
221 }\
222 kernelPtrRowEnd += kernelWidth;\
223 y++;\
224 }\
225 PX_COMMIT\
226 xStart++;\
227 PX_INCREMENT\
228 }\
229 \
230 /* B hrana */\
231 while (dPtr < dPtrNoReindexHorizontalLimit) {\
232 PX_INIT\
233 kernelPtr = kernel;\
234 kernelPtrRowEnd = kernelFirstRowEnd;\
235 y = yStart;\
236 while (kernelPtr < kernelEnd) {\
237 sPtr = src + yHi->reindex(y) * width + xStart;\
238 while (kernelPtr < kernelPtrRowEnd) {\
239 KERNEL_ACTION\
240 kernelPtr++;\
241 sPtr++;\
242 }\
243 kernelPtrRowEnd += kernelWidth;\
244 y++;\
245 }\
246 PX_COMMIT\
247 xStart++;\
248 PX_INCREMENT\
249 }\
250 \
251 /* BR roh */\
252 while (dPtr < dPtrHorizontalLimit) {\
253 PX_INIT\
254 kernelPtr = kernel;\
255 kernelPtrRowEnd = kernelFirstRowEnd;\
256 y = yStart;\
257 while (kernelPtr < kernelEnd) {\
258 x = xStart;\
259 while (kernelPtr < kernelPtrRowEnd) {\
260 sPtr = src + yHi->reindex(y) * width + xHi->reindex(x);\
261 KERNEL_ACTION\
262 kernelPtr++;\
263 x++;\
264 }\
265 kernelPtrRowEnd += kernelWidth;\
266 y++;\
267 }\
268 PX_COMMIT\
269 xStart++;\
270 PX_INCREMENT\
271 }\
272 \
273 dPtrInitReindexHorizontalLimit += width;\
274 dPtrNoReindexHorizontalLimit += width;\
275 dPtrHorizontalLimit += width;\
276 \
277 yStart++;\
278 \
279 ROW_INCREMENT\
280 \
281 }
282
283 namespace app {
284
285 template class TLinearFilter<px_4x8bit, px_1x8bit> ;
286 template class TLinearFilter<px_1x8bit, px_1x8bit> ;
287
288 template<typename TPIXEL, typename TCHANNEL>
289 int TLinearFilter<TPIXEL, TCHANNEL>::applyTo_1ch(TBitmap<TPIXEL, TCHANNEL> &bitmap, Rect dstArea) {
290 if (this->chCount != 1) {
291 return 1;
292 }
293
294 if (kernel == NULL || kernelWidth < 2 || kernelHeight < 2) {
295 return 2;
296 }
297 TPIXEL * const src = bitmap.getData();
298 if (src == NULL) {
299 return 3;
300 }
301 unsigned width = bitmap.getWidth();
302 unsigned height = bitmap.getHeight();
303 TPIXEL * const dst = (TPIXEL *) malloc(width * height * sizeof(TPIXEL));
304 if (dst == NULL) {
305 return 4;
306 }
307
308 PointerArea tmpArea(dst, bitmap.getRect(), dstArea, sizeof(TPIXEL));
309 Rect crop = tmpArea.getArea();
310 PointerArea srcArea = bitmap.getPointerArea();
311
312 int xMin = crop.tl.x;
313 int yMin = crop.tl.y;
314 int xMax = crop.br.x;
315 int yMax = crop.br.y;
316
317 int xNoReindexFrom = kernelWCenter < width ? kernelWCenter : width;
318 int xNoReindexTo = width - kernelWCenter;
319 int yNoReindexFrom = kernelHCenter < height ? kernelHCenter : height;
320 int yNoReindexTo = height - kernelHCenter;
321
322 MirroredReindexer *xLo = NULL, *xHi = NULL, *yLo = NULL, *yHi = NULL;
323
324 int initOk = 1;
325
326 if (xMin < xNoReindexFrom) {
327 xLo = new MirroredReindexer(-kernelWCenter, kernelWidth - 1, width);
328 if (xLo == NULL) {
329 initOk = 0;
330 } else if (xLo->getVals() == NULL) {
331 initOk = 0;
332 }
333 }
334
335 if (xNoReindexTo < xMax && initOk) {
336 xHi = new MirroredReindexer(width - kernelWidth - 1, width + kernelWCenter, width);
337 if (xHi == NULL) {
338 initOk = 0;
339 } else if (xHi->getVals() == NULL) {
340 initOk = 0;
341 }
342 }
343
344 if (yMin < yNoReindexFrom && initOk) {
345 yLo = new MirroredReindexer(-kernelHCenter, kernelHeight - 1, height);
346 if (yLo == NULL) {
347 initOk = 0;
348 } else if (yLo->getVals() == NULL) {
349 initOk = 0;
350 }
351 }
352
353 if (yNoReindexTo < yMax && initOk) {
354 yHi = new MirroredReindexer(height - kernelHeight - 1, height + kernelHCenter, height);
355 if (yHi == NULL) {
356 initOk = 0;
357 } else if (yHi->getVals() == NULL) {
358 initOk = 0;
359 }
360 }
361
362 if (initOk) {
363 TPIXEL * dPtr = dst + yMin * width + xMin;
364 int dPtrOffset = width - xMax + xMin;
365 double sum = 0;
366
367 LINEAR_FILTER_ALGORITHM_GENERAL( sum = 0;,
368
369 sum += *sPtr * *kernelPtr;,
370
371 sum += 0.5; *dPtr = (sum < 0) ? 0 : (sum > maxVal) ? maxVal : sum;,
372
373 dPtr++;,
374
375 dPtr += dPtrOffset;)
376
377 PointerArea::copy(srcArea, tmpArea, crop.tl);
378
379 }
380
381 if (xLo != NULL) {
382 delete xLo;
383 }
384
385 if (xHi != NULL) {
386 delete xHi;
387 }
388
389 if (yLo != NULL) {
390 delete yLo;
391 }
392
393 if (yHi != NULL) {
394 delete yHi;
395 }
396
397 free(dst);
398
399 if (initOk) {
400 return 0;
401 } else {
402 return 5;
403 }
404 }
405
406 template<typename TPIXEL, typename TCHANNEL>
407 int TLinearFilter<TPIXEL, TCHANNEL>::filterResult_4ch(TBitmap<TPIXEL, TCHANNEL> &bitmap, TBitmap<TPIXEL, TCHANNEL> &dstBitmap, Rect dstArea) {
408 if (this->chCount != 4) {
409 return 1;
410 }
411
412 if (kernel == NULL || kernelWidth < 2 || kernelHeight < 2) {
413 return 2;
414 }
415 TPIXEL * const src = bitmap.getData();
416 if (src == NULL) {
417 return 3;
418 }
419 unsigned width = bitmap.getWidth();
420 unsigned height = bitmap.getHeight();
421
422 TPIXEL * const dst = dstBitmap.getData();
423 if (dst == NULL) {
424 return 4;
425 }
426
427 // PointerArea tmpArea(dst, bitmap.getRect(), dstArea, sizeof(TPIXEL));
428 // Rect crop = tmpArea.getArea();
429 // PointerArea srcArea = bitmap.getPointerArea();
430
431 int xMin = dstArea.tl.x;
432 int yMin = dstArea.tl.y;
433 int xMax = dstArea.br.x;
434 int yMax = dstArea.br.y;
435
436 int xNoReindexFrom = kernelWCenter < width ? kernelWCenter : width;
437 int xNoReindexTo = width - kernelWCenter;
438 int yNoReindexFrom = kernelHCenter < height ? kernelHCenter : height;
439 int yNoReindexTo = height - kernelHCenter;
440
441 MirroredReindexer *xLo = NULL, *xHi = NULL, *yLo = NULL, *yHi = NULL;
442
443 int initOk = 1;
444
445 if (xMin < xNoReindexFrom) {
446 xLo = new MirroredReindexer(-kernelWCenter, kernelWidth - 1, width);
447 if (xLo == NULL) {
448 initOk = 0;
449 } else if (xLo->getVals() == NULL) {
450 initOk = 0;
451 }
452 }
453
454 if (xNoReindexTo < xMax && initOk) {
455 xHi = new MirroredReindexer(width - kernelWidth - 1, width + kernelWCenter, width);
456 if (xHi == NULL) {
457 initOk = 0;
458 } else if (xHi->getVals() == NULL) {
459 initOk = 0;
460 }
461 }
462
463 if (yMin < yNoReindexFrom && initOk) {
464 yLo = new MirroredReindexer(-kernelHCenter, kernelHeight - 1, height);
465 if (yLo == NULL) {
466 initOk = 0;
467 } else if (yLo->getVals() == NULL) {
468 initOk = 0;
469 }
470 }
471
472 if (yNoReindexTo < yMax && initOk) {
473 yHi = new MirroredReindexer(height - kernelHeight - 1, height + kernelHCenter, height);
474 if (yHi == NULL) {
475 initOk = 0;
476 } else if (yHi->getVals() == NULL) {
477 initOk = 0;
478 }
479 }
480
481 if (initOk) {
482 TPIXEL * dPtr = dst + yMin * width + xMin;
483 int dPtrOffset = width - xMax + xMin;
484
485 double sumR;
486 double sumG;
487 double sumB;
488 double sumA;
489 double A;
490
491 TCHANNEL * chPtr;
492 double kv;
493
494 LINEAR_FILTER_ALGORITHM_GENERAL( sumR = 0; sumG = 0; sumB = 0; sumA = 0;,
495
496 kv = *kernelPtr; chPtr = (TCHANNEL *) sPtr; A = *(chPtr + 3) * kv; sumR += *(chPtr++) * A; sumG += *(chPtr++) * A; sumB += *chPtr * A; sumA += A;,
497
498 chPtr = (TCHANNEL *) dPtr;
499
500 sumR += 0.5; sumG += 0.5; sumB += 0.5; sumA += 0.5;
501
502 sumA = (sumA < 0) ? 0 : (sumA > maxVal) ? maxVal : sumA;
503
504 sumR = sumR / sumA + 0.5; sumG = sumG / sumA + 0.5; sumB = sumB / sumA + 0.5;
505
506 *chPtr = (sumR < 0) ? 0 : (sumR > maxVal) ? maxVal : sumR; chPtr++; *chPtr = (sumG < 0) ? 0 : (sumG > maxVal) ? maxVal : sumG; chPtr++; *chPtr = (sumB < 0) ? 0 : (sumB > maxVal) ? maxVal : sumB; chPtr++; *chPtr = sumA;,
507
508 dPtr++;,
509
510 dPtr += dPtrOffset;)
511
512 // PointerArea::copy(srcArea, tmpArea, crop.tl);
513
514 }
515
516 if (xLo != NULL) {
517 delete xLo;
518 }
519
520 if (xHi != NULL) {
521 delete xHi;
522 }
523
524 if (yLo != NULL) {
525 delete yLo;
526 }
527
528 if (yHi != NULL) {
529 delete yHi;
530 }
531
532 if (initOk) {
533 return 0;
534 } else {
535 return 5;
536 }
537 }
538
539 template<typename TPIXEL, typename TCHANNEL> int TLinearFilter<TPIXEL, TCHANNEL>::applyTo_4ch(TBitmap<TPIXEL, TCHANNEL> &bitmap, Rect dstRect) {
540 if (this->chCount != 4) {
541 return 1;
542 }
543 TBitmap<TPIXEL, TCHANNEL> * tmp = new TBitmap<TPIXEL, TCHANNEL>(bitmap.getWidth(), bitmap.getHeight(), bitmap.getType(), bitmap.isPremultiplied());
544 if (tmp == NULL) {
545 return 2;
546 }
547 PointerArea tmpArea(tmp->getData(), tmp->getRect(), dstRect, sizeof(TPIXEL));
548 Rect crop = tmpArea.getArea();
549 PointerArea srcArea = bitmap.getPointerArea();
550
551 int err = filterResult_4ch(bitmap, *tmp, crop);
552 if (err) {
553 delete tmp;
554 return 100 + err;
555 }
556
557 PointerArea::copy(srcArea, tmpArea, crop.tl);
558
559 delete tmp;
560
561 return 0;
562 }
563 template<typename TPIXEL, typename TCHANNEL> int TLinearFilter<TPIXEL, TCHANNEL>::applyTo_4ch(TBitmap<TPIXEL, TCHANNEL> &bitmap, Rect dstRect, double alpha) {
564 if (this->chCount != 4) {
565 return 1;
566 }
567 TBitmap<TPIXEL, TCHANNEL> * tmp = new TBitmap<TPIXEL, TCHANNEL>(bitmap.getWidth(), bitmap.getHeight(), bitmap.getType(), bitmap.isPremultiplied());
568 if (tmp == NULL) {
569 return 2;
570 }
571
572 PointerArea tmpArea(tmp->getData(), tmp->getRect(), dstRect, sizeof(TPIXEL));
573 Rect crop = tmpArea.getArea();
574 PointerArea srcArea = bitmap.getPointerArea();
575
576 int err = filterResult_4ch(bitmap, *tmp, crop);
577 if (err) {
578 delete tmp;
579 return 100 + err;
580 }
581
582 TBitmap<TPIXEL, TCHANNEL> * dst = &bitmap;
583
584 Blender::blendTo(BLEND_MODE_NORMAL, *(TBitmap<px_4x8bit, px_1x8bit> *) dst, *(TBitmap<px_4x8bit, px_1x8bit> *) tmp, crop, crop.tl, alpha);
585
586 delete tmp;
587
588 return 0;
589 }
590
591 template<typename TPIXEL, typename TCHANNEL> int TLinearFilter<TPIXEL, TCHANNEL>::applyTo_4ch(TBitmap<TPIXEL, TCHANNEL> &bitmap, TBitmap<TCHANNEL, TCHANNEL> &msk, Rect mskRect,
592 Point mskOrig) {
593 if (this->chCount != 4) {
594 return 1;
595 }
596 TBitmap<TPIXEL, TCHANNEL> * tmp = new TBitmap<TPIXEL, TCHANNEL>(bitmap.getWidth(), bitmap.getHeight(), bitmap.getType(), bitmap.isPremultiplied());
597 if (tmp == NULL) {
598 return 2;
599 }
600
601 PointerArea mskArea(msk.getData(), msk.getRect(), mskRect, sizeof(TCHANNEL));
602 PointerArea srcArea = bitmap.getPointerArea();
603
604 int err = PointerArea::makeCommon(srcArea, mskArea, mskOrig);
605 if (err) {
606 return 200 + err;
607 }
608
609 Rect crop = srcArea.getArea();
610 Rect mskCrop = mskArea.getArea();
611
612 err = filterResult_4ch(bitmap, *tmp, crop);
613 if (err) {
614 delete tmp;
615 return 100 + err;
616 }
617
618 TBitmap<TPIXEL, TCHANNEL> * dst = &bitmap;
619
620 Blender::drawTo(BLEND_MODE_NORMAL, *(TBitmap<px_4x8bit, px_1x8bit> *) dst, msk, *(TBitmap<px_4x8bit, px_1x8bit> *) tmp, mskCrop, Point(0, 0), crop.tl);
621
622 delete tmp;
623
624 return 0;
625 }
626
627 template<typename TPIXEL, typename TCHANNEL> int TLinearFilter<TPIXEL, TCHANNEL>::applyTo_4ch(TBitmap<TPIXEL, TCHANNEL> &bitmap, TBitmap<TCHANNEL, TCHANNEL> &msk, Rect mskRect,
628 Point mskOrig, double alpha) {
629 if (this->chCount != 4) {
630 return 1;
631 }
632 TBitmap<TPIXEL, TCHANNEL> * tmp = new TBitmap<TPIXEL, TCHANNEL>(bitmap.getWidth(), bitmap.getHeight(), bitmap.getType(), bitmap.isPremultiplied());
633 if (tmp == NULL) {
634 return 2;
635 }
636
637 PointerArea mskArea(msk.getData(), msk.getRect(), mskRect, sizeof(TCHANNEL));
638 PointerArea srcArea = bitmap.getPointerArea();
639
640 int err = PointerArea::makeCommon(srcArea, mskArea, mskOrig);
641 if (err) {
642 return 200 + err;
643 }
644
645 Rect crop = srcArea.getArea();
646 Rect mskCrop = mskArea.getArea();
647
648 err = filterResult_4ch(bitmap, *tmp, crop);
649 if (err) {
650 delete tmp;
651 return 100 + err;
652 }
653
654 TBitmap<TPIXEL, TCHANNEL> * dst = &bitmap;
655
656 Blender::drawTo(BLEND_MODE_NORMAL, *(TBitmap<px_4x8bit, px_1x8bit> *) dst, msk, *(TBitmap<px_4x8bit, px_1x8bit> *) tmp, mskCrop, Point(0, 0), crop.tl, alpha);
657
658 delete tmp;
659
660 return 0;
661 }
662
663 template<typename TPIXEL, typename TCHANNEL>
664 TLinearFilter<TPIXEL, TCHANNEL>::~TLinearFilter() {
665 if (kernel != NULL) {
666 free (kernel);
667 }
668 }
669
670 } /* namespace app */