App
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 
287 
288 template<typename TPIXEL, typename TCHANNEL>
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 
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>
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 
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 
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>
665  if (kernel != NULL) {
666  free (kernel);
667  }
668 }
669 
670 } /* namespace app */