/* * This file is part of RawTherapee. * * Copyright © 2010 Emil Martinec * * RawTherapee is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * RawTherapee is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ #ifndef _BOXBLUR_H_ #define _BOXBLUR_H_ #include #include #include #include "alignedbuffer.h" #ifdef _OPENMP #include #endif #include "rt_math.h" #include "opthelper.h" //using namespace rtengine; namespace rtengine { // classical filtering if the support window is small: template void boxblur (T** src, A** dst, int radx, int rady, int W, int H) { //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //box blur image; box range = (radx,rady) AlignedBuffer* buffer = new AlignedBuffer (W*H); float* temp = buffer->data; if (radx==0) { #ifdef _OPENMP #pragma omp parallel for #endif for (int row=0; row SSEFUNCTION void boxblur (T* src, A* dst, int radx, int rady, int W, int H) { //printf("boxblur\n"); //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //box blur image; box range = (radx,rady) i.e. box size is (2*radx+1)x(2*rady+1) AlignedBuffer* buffer = new AlignedBuffer (W*H); float* temp = buffer->data; if (radx==0) { for (int row=0; row void boxvar (T* src, T* dst, int radx, int rady, int W, int H) { AlignedBuffer buffer1(W*H); AlignedBuffer buffer2(W*H); float* tempave = buffer1.data; float* tempsqave = buffer2.data; AlignedBufferMP buffer3(H); //float image_ave = 0; //box blur image channel; box size = 2*box+1 //horizontal blur #ifdef _OPENMP #pragma omp parallel for #endif for (int row = 0; row < H; row++) { int len = radx + 1; tempave[row*W+0] = src[row*W+0]/len; tempsqave[row*W+0] = SQR(src[row*W+0])/len; for (int j=1; j<=radx; j++) { tempave[row*W+0] += src[row*W+j]/len; tempsqave[row*W+0] += SQR(src[row*W+j])/len; } for (int col=1; col<=radx; col++) { tempave[row*W+col] = (tempave[row*W+col-1]*len + src[row*W+col+radx])/(len+1); tempsqave[row*W+col] = (tempsqave[row*W+col-1]*len + SQR(src[row*W+col+radx]))/(len+1); len ++; } for (int col = radx+1; col < W-radx; col++) { tempave[row*W+col] = tempave[row*W+col-1] + (src[row*W+col+radx] - src[row*W+col-radx-1])/len; tempsqave[row*W+col] = tempsqave[row*W+col-1] + (SQR(src[row*W+col+radx]) - SQR(src[row*W+col-radx-1]))/len; } for (int col=W-radx; col* pBuf3 = buffer3.acquire(); T* tempave2=(T*)pBuf3->data; int len = rady + 1; tempave2[0] = tempave[0*W+col]/len; dst[0*W+col] = tempsqave[0*W+col]/len; for (int i=1; i<=rady; i++) { tempave2[0] += tempave[i*W+col]/len; dst[0*W+col] += tempsqave[i*W+col]/len; } for (int row=1; row<=rady; row++) { tempave2[row] = (tempave2[(row-1)]*len + tempave[(row+rady)*W+col])/(len+1); dst[row*W+col] = (dst[(row-1)*W+col]*len + tempsqave[(row+rady)*W+col])/(len+1); len ++; } for (int row = rady+1; row < H-rady; row++) { tempave2[row] = tempave2[(row-1)] + (tempave[(row+rady)*W+col] - tempave[(row-rady-1)*W+col])/len; dst[row*W+col] = dst[(row-1)*W+col] + (tempsqave[(row+rady)*W+col] - tempsqave[(row-rady-1)*W+col])/len; } for (int row=H-rady; row void boxdev (T* src, T* dst, int radx, int rady, int W, int H) { //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //box blur image; box range = (radx,rady) i.e. box size is (2*radx+1)x(2*rady+1) AlignedBuffer* buffer1 = new AlignedBuffer (W*H); float* temp = buffer1->data; AlignedBuffer* buffer2 = new AlignedBuffer (W*H); float* tempave = buffer2->data; if (radx==0) { #ifdef _OPENMP #pragma omp parallel for #endif for (int row=0; row void boxsqblur (T* src, A* dst, int radx, int rady, int W, int H) { //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //box blur image; box range = (radx,rady) i.e. box size is (2*radx+1)x(2*rady+1) AlignedBuffer* buffer = new AlignedBuffer (W*H); float* temp = buffer->data; if (radx==0) { #ifdef _OPENMP #pragma omp parallel for #endif for (int row=0; row void boxcorrelate (T* src, A* dst, int dx, int dy, int radx, int rady, int W, int H) { //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //box blur image; box range = (radx,rady) i.e. box size is (2*radx+1)x(2*rady+1) AlignedBuffer* buffer = new AlignedBuffer (W*H); float* temp = buffer->data; if (radx==0) { for (int row=0; row0 ? (src[row*W+col])*(src[rr*W+cc]) : 0; } } } else { //horizontal blur for (int row = 0; row < H; row++) { int len = radx + 1; int rr = min(H-1,max(0,row+dy)); int cc = min(W-1,max(0,0+dx)); temp[row*W+0] = ((float)src[row*W+0])*(src[rr*W+cc])/len; for (int j=1; j<=radx; j++) { int cc = min(W-1,max(0,j+dx)); temp[row*W+0] += ((float)src[row*W+j])*(src[rr*W+cc])/len; } for (int col=1; col<=radx; col++) { int cc = min(W-1,max(0,col+dx+radx)); temp[row*W+col] = (temp[row*W+col-1]*len + (src[row*W+col+radx])*(src[rr*W+cc]))/(len+1); len ++; } for (int col = radx+1; col < W-radx; col++) { int cc = min(W-1,max(0,col+dx+radx)); int cc1 = min(W-1,max(0,col+dx-radx-1)); temp[row*W+col] = temp[row*W+col-1] + ((float)((src[row*W+col+radx])*(src[rr*W+cc]) - (src[row*W+col-radx-1])*(src[rr*W+cc1])))/len; } for (int col=W-radx; col SSEFUNCTION void boxabsblur (T* src, A* dst, int radx, int rady, int W, int H, float * temp) { //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //box blur image; box range = (radx,rady) i.e. box size is (2*radx+1)x(2*rady+1) if (radx==0) { for (int row=0; row