10#include "matrixCT.hpp"
11#include "fimImgOps.hpp"
12#include "FgApproxFunc.hpp"
26 float lo = (float)ii * ss + pp + 0.5f;
30 float lo = ((float)ii + 0.5f) * ss + pp;
36float weightFn(
int rasterPos,Vec2F boundsPacs,Vec2I boundFloors)
38 if (rasterPos == boundFloors[0]) {
39 if (rasterPos == boundFloors[1])
40 return boundsPacs[1] - boundsPacs[0];
42 return scast<float>(boundFloors[0] + 1) - boundsPacs[0];
44 else if (rasterPos == boundFloors[1])
45 return boundsPacs[1] - scast<float>(boundFloors[1]);
60 const FimImgRgbaUbC &srcImg,
61 FimImgRgbaUbC &dstImg)
63 FGASSERT(srcImg.imageAllocated());
64 FGASSERT(a_hi.x1 > a_lo.x1);
65 FGASSERT(a_hi.x2 > a_lo.x2);
68 dstImg.resize(a_w,a_h);
69 Vec2I srcDims {scast<int>(srcImg.width()),scast<int>(srcImg.height())};
70 Rgba8 *dstRowPtr =
reinterpret_cast<Rgba8*
>(dstImg.imageData());
72 (a_hi.x1 - a_lo.x1) / scast<float>(a_w),
73 (a_hi.x2 - a_lo.x2) / scast<float>(a_h),
75 for (uint yy=0; yy<a_h; yy++) {
76 Rgba8 *dPtr = dstRowPtr;
77 Vec2F boundsPacsY = getBoundsPacs(yy,invScale[1],a_lo.x2);
78 Vec2I boundFloorsY {mapFloor(boundsPacsY)};
79 for (uint xx=0; xx<a_w; xx++) {
80 Vec2F boundsPacsX = getBoundsPacs(xx,invScale[0],a_lo.x1);
81 Vec2I boundFloorsX {mapFloor(boundsPacsX)};
84 for (
int yyy=boundFloorsY[0]; yyy<=boundFloorsY[1]; yyy++) {
85 float weightY = weightFn(yyy,boundsPacsY,boundFloorsY);
86 for (
int xxx=boundFloorsX[0]; xxx<=boundFloorsX[1]; xxx++) {
87 float weightX = weightFn(xxx,boundsPacsX,boundFloorsX);
88 float currWgt = weightX * weightY;
90 if ((xxx >= 0) && (xxx < srcDims[0]) && (yyy >= 0) && (yyy < srcDims[1])) {
91 Rgba8
const *sPtr =
reinterpret_cast<Rgba8
const *
>(srcImg.imageData()) + yyy * srcImg.width() + xxx;
94 acc[0] += curr[0] * curr[3];
95 acc[1] += curr[1] * curr[3];
96 acc[2] += curr[2] * curr[3];
102 *(dPtr++) = Rgba8{0};
105 (uchar)(acc[0] / acc[3] + 0.5f),
106 (uchar)(acc[1] / acc[3] + 0.5f),
107 (uchar)(acc[2] / acc[3] + 0.5f),
108 (uchar)(acc[3] / accW + 0.5f),
112 dstRowPtr += dstImg.width();
118crop(uint hiBound,
int val,
float & wgt)
124 else if (val >
static_cast<int>(hiBound)) {
133 const FimImgRgbaUbC &img,
137 uint ncols = img.width();
138 uint nrows = img.height();
139 FGASSERT_FAST(img.imageAllocated());
140 FGASSERT_FAST(ncols > 0);
141 FGASSERT_FAST(nrows > 0);
143 posRcs.x1 = (x + 1.0f) * img.width() * 0.5f - 0.5f;
144 posRcs.x2 = (1.0f - y) * img.height() * 0.5f - 0.5f;
145 float xf = std::floor(posRcs.x1),
146 yf = std::floor(posRcs.x2),
153 uint rowLo = crop(nrows-1,yfi,yl),
154 rowHi = crop(nrows-1,yfi+1,yh),
155 colLo = crop(ncols-1,xfi,xl),
156 colHi = crop(ncols-1,xfi+1,xh);
158 pixLL,pixHL,pixLH,pixHH;
159 futConvert(img[rowLo][colLo],pixLL);
160 futConvert(img[rowHi][colLo],pixHL);
161 futConvert(img[rowLo][colHi],pixLH);
162 futConvert(img[rowHi][colHi],pixHH);
163 retval = pixLL * yl * xl +
172 const FimImgRgbaFC &img,
176 uint ncols = img.width();
177 uint nrows = img.height();
178 FGASSERT_FAST(img.imageAllocated());
179 FGASSERT_FAST(ncols > 0);
180 FGASSERT_FAST(nrows > 0);
182 posRcs.x1 = (x + 1.0f) * img.width() * 0.5f - 0.5f;
183 posRcs.x2 = (1.0f - y) * img.height() * 0.5f - 0.5f;
184 int rowFloor = futFloor(posRcs.x2),
185 colFloor = futFloor(posRcs.x1);
186 float rh = posRcs.x2 - rowFloor;
187 float ch = posRcs.x1 - colFloor;
188 float rl = 1.0f - rh;
189 float cl = 1.0f - ch;
190 uint rowLo = crop(nrows-1,rowFloor,rl),
191 rowHi = crop(nrows-1,rowFloor+1,rh),
192 colLo = crop(ncols-1,colFloor,cl),
193 colHi = crop(ncols-1,colFloor+1,ch);
195 img[rowLo][colLo] * rl * cl +
196 img[rowHi][colLo] * rh * cl +
197 img[rowLo][colHi] * rl * ch +
198 img[rowHi][colHi] * rh * ch;
215 const FimImgRgbaUbC& src,
218 FGASSERT(src.imageAllocated());
220 uint dstWid = src.width() / 2,
221 dstHgt = src.height() / 2;
222 dst.resize(dstWid,dstHgt);
224 uint srcStep = src.widthStepType();
225 uint dstStep = dst.widthStepType();
226 const FimRgbaUbC *srcPtr1 = src.imageData(),
227 *srcPtr2 = srcPtr1 + srcStep;
228 FimRgbaUbC *dstPtr = dst.imageData();
231 for (yd=0; yd<dst.height(); yd++)
233 for (xd=0; xd<dst.width(); xd++)
238 dstPtr[xd].c[FIMRGBA_R] = (uchar)(
239 ((uint)srcPtr1[xs1].c[FIMRGBA_R] + (uint)srcPtr1[xs2].c[FIMRGBA_R] +
240 (uint)srcPtr2[xs1].c[FIMRGBA_R] + (uint)srcPtr2[xs2].c[FIMRGBA_R]) >> 2);
241 dstPtr[xd].c[FIMRGBA_G] = (uchar)(
242 ((uint)srcPtr1[xs1].c[FIMRGBA_G] + (uint)srcPtr1[xs2].c[FIMRGBA_G] +
243 (uint)srcPtr2[xs1].c[FIMRGBA_G] + (uint)srcPtr2[xs2].c[FIMRGBA_G]) >> 2);
244 dstPtr[xd].c[FIMRGBA_B] = (uchar)(
245 ((uint)srcPtr1[xs1].c[FIMRGBA_B] + (uint)srcPtr1[xs2].c[FIMRGBA_B] +
246 (uint)srcPtr2[xs1].c[FIMRGBA_B] + (uint)srcPtr2[xs2].c[FIMRGBA_B]) >> 2);
247 dstPtr[xd].c[FIMRGBA_A] = (uchar)(
248 ((uint)srcPtr1[xs1].c[FIMRGBA_A] + (uint)srcPtr1[xs2].c[FIMRGBA_A] +
249 (uint)srcPtr2[xs1].c[FIMRGBA_A] + (uint)srcPtr2[xs2].c[FIMRGBA_A]) >> 2);
252 srcPtr1 += 2 * srcStep;
253 srcPtr2 += 2 * srcStep;
259 const FimImgRgbaFC& src,
262 FGASSERT(src.imageAllocated());
264 uint dstWid = src.width() / 2,
265 dstHgt = src.height() / 2;
266 dst.resize(dstWid,dstHgt);
268 uint srcStep = src.widthStepType();
269 uint dstStep = dst.widthStepType();
270 const FimRgbaFC *srcPtr1 = src.imageData(),
271 *srcPtr2 = srcPtr1 + srcStep;
272 FimRgbaFC *dstPtr = dst.imageData();
275 for (yd=0; yd<dst.height(); yd++)
277 for (xd=0; xd<dst.width(); xd++)
282 dstPtr[xd].c[FIMRGBA_R] =
283 (srcPtr1[xs1].c[FIMRGBA_R] + srcPtr1[xs2].c[FIMRGBA_R] +
284 srcPtr2[xs1].c[FIMRGBA_R] + srcPtr2[xs2].c[FIMRGBA_R]) * 0.25f;
285 dstPtr[xd].c[FIMRGBA_G] =
286 (srcPtr1[xs1].c[FIMRGBA_G] + srcPtr1[xs2].c[FIMRGBA_G] +
287 srcPtr2[xs1].c[FIMRGBA_G] + srcPtr2[xs2].c[FIMRGBA_G]) * 0.25f;
288 dstPtr[xd].c[FIMRGBA_B] =
289 (srcPtr1[xs1].c[FIMRGBA_B] + srcPtr1[xs2].c[FIMRGBA_B] +
290 srcPtr2[xs1].c[FIMRGBA_B] + srcPtr2[xs2].c[FIMRGBA_B]) * 0.25f;
291 dstPtr[xd].c[FIMRGBA_A] =
292 (srcPtr1[xs1].c[FIMRGBA_A] + srcPtr1[xs2].c[FIMRGBA_A] +
293 srcPtr2[xs1].c[FIMRGBA_A] + srcPtr2[xs2].c[FIMRGBA_A]) * 0.25f;
296 srcPtr1 += 2 * srcStep;
297 srcPtr2 += 2 * srcStep;
310void fgImgShrinkInt(
const FimImgRgbaUbC& src,FimImgRgbaUbC& dst,uint factor)
312 if (factor == 1) {dst = src;
return; }
313 dst.resize(src.width()/factor,src.height()/factor);
314 FimImgRgbaUsC buffImg(1,dst.width());
315 ushort divisor = ushort(factor * factor);
316 FimRgbaUsC offset = FimRgbaUsC(divisor/2-1);
317 for (uint rowDst=0; rowDst<dst.height(); rowDst++)
319 buffImg.fill(FimRgbaUsC(0));
321 for (uint rowSrc=0; rowSrc<factor; rowSrc++)
323 buffPtr = buffImg.imageData();
324 const FimRgbaUbC *srcPtr = &src[rowDst*factor+rowSrc][0];
325 for (uint colDst=0; colDst<dst.width(); colDst++)
327 for (uint colSrc=0; colSrc<factor; colSrc++)
329 FimRgbaUsC tmp = FimRgbaUsC(*srcPtr++);
335 buffPtr = buffImg.imageData();
336 FimRgbaUbC *dstPtr = &dst[rowDst][0];
337 for (uint colDst=0; colDst<dst.width(); colDst++)
338 *dstPtr++ = FimRgbaUbC(((*buffPtr++)+offset)/divisor);
348void fimMultAccConvRoi(
351 const FimImgT<schar> &imgInp,
352 FimImgT<int> &imgOut,
356 FGASSERT(imgInp.imageAllocated());
357 uint widIn = imgInp.width(),
358 hgtIn = imgInp.height(),
359 wid = imgOut.width(),
360 hgt = imgOut.height();
361 FGASSERT((widIn+offx < wid) && (hgtIn+offy < hgt));
363 const schar *img1Ptr = imgInp.imageData();
364 int *img2Ptr = &imgOut[offy][offx];
365 uint img1step = imgInp.widthStepType(),
366 img2Step = imgOut.widthStepType();
368 for (uint yy=0; yy<hgtIn; yy++)
370 for (uint xx=0; xx<widIn; xx++)
371 img2Ptr[xx] += val *
int(img1Ptr[xx]);
390 m_gamma(gamma), m_black(black/255.0f), m_gain(gain)
394 operator()(
float val)
396 float ftmp = std::pow(val,m_gamma) * m_gain - m_black;
397 if (ftmp < 0.0f) ftmp = 0.0f;
398 if (ftmp > 1.0f) ftmp = 1.0f;
410 ZgaOp(FgApproxFunc<float> af)
416 const FimRgbaFC & src,
419 if (src.c[FIMRGBA_A] > 0.0f)
421 float alpha = src.c[FIMRGBA_A],
423 ftmp = m_af(src.c[FIMRGBA_R] / alpha) * alpha;
424 if (ftmp > 255.0f) ftmp = 255.0f;
425 dst.c[FIMRGBA_R] = ftmp;
426 ftmp = m_af(src.c[FIMRGBA_G] / alpha) * alpha;
427 if (ftmp > 255.0f) ftmp = 255.0f;
428 dst.c[FIMRGBA_G] = ftmp;
429 ftmp = m_af(src.c[FIMRGBA_B] / alpha) * alpha;
430 if (ftmp > 255.0f) ftmp = 255.0f;
431 dst.c[FIMRGBA_B] = ftmp;
432 dst.c[FIMRGBA_A] = alpha;
438 FgApproxFunc<float> m_af;
446 const FimImgRgbaFC &src,
449 FGASSERT(src.imageAllocated());
452 Zga(gamma,black,gain),
456 fimLoopBinary(ZgaOp(af),src,dst);
463void fimMirrorDetailDiff(FimImgRgbaFC& img)
465 uint wid = img.width(),
467 for (uint row=0; row<hgt; row++)
469 for (uint col=0; col<wid/2; col++)
471 FimRgbaFC &vl = img[row][col];
472 FimRgbaFC &vr = img[row][wid-col-1];
473 FimRgbaFC vnew = vl + vr;
486 const FimRgbaFC * src,
495 for (xx=0; xx<wid-2; xx++)
497 dst[xx] = acc[0] + acc[1]*2.0f + acc[2];
502 dst[xx++] = acc[0] + acc[1]*2.0f + acc[2];
503 dst[xx] = acc[1] + acc[2]*3.0f;
509 const FimImgRgbaFC & src,
512 FGASSERT((src.width() > 1) && (src.height() > 1));
513 dst.resize(src.width(),src.height());
514 const float denom = 1.0f / 16.0f;
515 FimImgRgbaFC acc(src.width(),3);
516 const FimRgbaFC *srcPtr = src.imageData();
517 FimRgbaFC *dstPtr = dst.imageData();
518 FimRgbaFC *accPtr0 = acc.imageData(),
519 *accPtr1 = accPtr0 + acc.widthStepType(),
520 *accPtr2 = accPtr1 + acc.widthStepType(),
522 smoothHoriz(srcPtr,accPtr0,src.width());
523 srcPtr += src.widthStepType();
524 smoothHoriz(srcPtr,accPtr1,src.width());
525 srcPtr += src.widthStepType();
526 smoothHoriz(srcPtr,accPtr2,src.width());
527 for (uint xx=0; xx<src.width(); xx++)
529 FimRgbaFC tmp = accPtr0[xx] * 3.0f + accPtr1[xx];
530 dstPtr[xx] = tmp * denom;
532 dstPtr += dst.widthStepType();
533 for (uint yy=1; yy<src.height(); yy++)
535 for (uint xx=0; xx<src.width(); xx++)
537 FimRgbaFC tmp = accPtr0[xx] + accPtr1[xx] * 2.0f + accPtr2[xx];
538 dstPtr[xx] = tmp * denom;
543 srcPtr += src.widthStepType();
544 dstPtr += dst.widthStepType();
545 if (yy < src.height()-2)
548 smoothHoriz(srcPtr,accPtr2,src.width());