diff --git a/rtengine/CA_correct_RT.cc b/rtengine/CA_correct_RT.cc index ab0b95a27..64bb19113 100644 --- a/rtengine/CA_correct_RT.cc +++ b/rtengine/CA_correct_RT.cc @@ -26,6 +26,7 @@ #include "rtengine.h" #include "rawimagesource.h" #include "rt_math.h" +#include "median.h" namespace { @@ -106,14 +107,6 @@ bool LinEqSolve(int nDim, double* pfMatr, double* pfVect, double* pfSolution) //end of linear equation solver //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -inline void pixSort(float &a, float &b) { - if (a > b) { - float temp = a; - a = b; - b = temp; - } -} - } using namespace std; @@ -630,36 +623,18 @@ void RawImageSource::CA_correct_RT(const double cared, const double cablue, cons float bstemp[2]; for (int dir = 0; dir < 2; dir++) { //temporary storage for median filter - float p[9]; - p[0] = blockshifts[(vblock - 1) * hblsz + hblock - 1][c][dir]; - p[1] = blockshifts[(vblock - 1) * hblsz + hblock][c][dir]; - p[2] = blockshifts[(vblock - 1) * hblsz + hblock + 1][c][dir]; - p[3] = blockshifts[(vblock) * hblsz + hblock - 1][c][dir]; - p[4] = blockshifts[(vblock) * hblsz + hblock][c][dir]; - p[5] = blockshifts[(vblock) * hblsz + hblock + 1][c][dir]; - p[6] = blockshifts[(vblock + 1) * hblsz + hblock - 1][c][dir]; - p[7] = blockshifts[(vblock + 1) * hblsz + hblock][c][dir]; - p[8] = blockshifts[(vblock + 1) * hblsz + hblock + 1][c][dir]; - pixSort(p[1], p[2]); - pixSort(p[4], p[5]); - pixSort(p[7], p[8]); - pixSort(p[0], p[1]); - pixSort(p[3], p[4]); - pixSort(p[6], p[7]); - pixSort(p[1], p[2]); - pixSort(p[4], p[5]); - pixSort(p[7], p[8]); - pixSort(p[0], p[3]); - pixSort(p[5], p[8]); - pixSort(p[4], p[7]); - pixSort(p[3], p[6]); - pixSort(p[1], p[4]); - pixSort(p[2], p[5]); - pixSort(p[4], p[7]); - pixSort(p[4], p[2]); - pixSort(p[6], p[4]); - pixSort(p[4], p[2]); - bstemp[dir] = p[4]; + const std::array p = { + blockshifts[(vblock - 1) * hblsz + hblock - 1][c][dir], + blockshifts[(vblock - 1) * hblsz + hblock][c][dir], + blockshifts[(vblock - 1) * hblsz + hblock + 1][c][dir], + blockshifts[(vblock) * hblsz + hblock - 1][c][dir], + blockshifts[(vblock) * hblsz + hblock][c][dir], + blockshifts[(vblock) * hblsz + hblock + 1][c][dir], + blockshifts[(vblock + 1) * hblsz + hblock - 1][c][dir], + blockshifts[(vblock + 1) * hblsz + hblock][c][dir], + blockshifts[(vblock + 1) * hblsz + hblock + 1][c][dir] + }; + bstemp[dir] = median(p); } //now prepare coefficient matrix; use only data points within caautostrength/2 std devs of zero diff --git a/rtengine/FTblockDN.cc b/rtengine/FTblockDN.cc index 71c65cfb0..288c9c994 100644 --- a/rtengine/FTblockDN.cc +++ b/rtengine/FTblockDN.cc @@ -22,7 +22,7 @@ // //////////////////////////////////////////////////////////////// -#include +#include #include #include "../rtgui/threadutils.h" #include "rtengine.h" @@ -36,6 +36,7 @@ #include "sleef.c" #include "opthelper.h" #include "cplx_wavelet_dec.h" +#include "median.h" #ifdef _OPENMP #include @@ -48,52 +49,6 @@ #define epsilon 0.001f/(TS*TS) //tolerance -#define med2(a0,a1,a2,a3,a4,median) { \ -pp[0]=a0; pp[1]=a1; pp[2]=a2; pp[3]=a3; pp[4]=a4; \ -PIX_SORT(pp[0],pp[1]) ; PIX_SORT(pp[3],pp[4]) ; PIX_SORT(pp[0],pp[3]) ;\ -PIX_SORT(pp[1],pp[4]) ; PIX_SORT(pp[1],pp[2]) ; PIX_SORT(pp[2],pp[3]) ;\ -PIX_SORT(pp[1],pp[2]) ; median=pp[2] ;} - -#define med5(a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20,a21,a22,a23,a24,median) { \ -pp[0]=a0; pp[1]=a1; pp[2]=a2; pp[3]=a3; pp[4]=a4; pp[5]=a5; pp[6]=a6; pp[7]=a7; pp[8]=a8; pp[9]=a9; pp[10]=a10; pp[11]=a11; pp[12]=a12; \ -pp[13]=a13; pp[14]=a14; pp[15]=a15; pp[16]=a16; pp[17]=a17; pp[18]=a18; pp[19]=a19; pp[20]=a20; pp[21]=a21; pp[22]=a22; pp[23]=a23; pp[24]=a24; \ -PIX_SORT(pp[0], pp[1]) ; PIX_SORT(pp[3], pp[4]) ; PIX_SORT(pp[2], pp[4]) ;\ -PIX_SORT(pp[2], pp[3]) ; PIX_SORT(pp[6], pp[7]) ; PIX_SORT(pp[5], pp[7]) ;\ -PIX_SORT(pp[5], pp[6]) ; PIX_SORT(pp[9], pp[10]) ; PIX_SORT(pp[8], pp[10]) ;\ -PIX_SORT(pp[8], pp[9]) ; PIX_SORT(pp[12], pp[13]) ; PIX_SORT(pp[11], pp[13]) ;\ -PIX_SORT(pp[11], pp[12]) ; PIX_SORT(pp[15], pp[16]) ; PIX_SORT(pp[14], pp[16]) ;\ -PIX_SORT(pp[14], pp[15]) ; PIX_SORT(pp[18], pp[19]) ; PIX_SORT(pp[17], pp[19]) ;\ -PIX_SORT(pp[17], pp[18]) ; PIX_SORT(pp[21], pp[22]) ; PIX_SORT(pp[20], pp[22]) ;\ -PIX_SORT(pp[20], pp[21]) ; PIX_SORT(pp[23], pp[24]) ; PIX_SORT(pp[2], pp[5]) ;\ -PIX_SORT(pp[3], pp[6]) ; PIX_SORT(pp[0], pp[6]) ; PIX_SORT(pp[0], pp[3]) ;\ -PIX_SORT(pp[4], pp[7]) ; PIX_SORT(pp[1], pp[7]) ; PIX_SORT(pp[1], pp[4]) ;\ -PIX_SORT(pp[11], pp[14]) ; PIX_SORT(pp[8], pp[14]) ; PIX_SORT(pp[8], pp[11]) ;\ -PIX_SORT(pp[12], pp[15]) ; PIX_SORT(pp[9], pp[15]) ; PIX_SORT(pp[9], pp[12]) ;\ -PIX_SORT(pp[13], pp[16]) ; PIX_SORT(pp[10], pp[16]) ; PIX_SORT(pp[10], pp[13]) ;\ -PIX_SORT(pp[20], pp[23]) ; PIX_SORT(pp[17], pp[23]) ; PIX_SORT(pp[17], pp[20]) ;\ -PIX_SORT(pp[21], pp[24]) ; PIX_SORT(pp[18], pp[24]) ; PIX_SORT(pp[18], pp[21]) ;\ -PIX_SORT(pp[19], pp[22]) ; PIX_SORT(pp[8], pp[17]) ; PIX_SORT(pp[9], pp[18]) ;\ -PIX_SORT(pp[0], pp[18]) ; PIX_SORT(pp[0], pp[9]) ; PIX_SORT(pp[10], pp[19]) ;\ -PIX_SORT(pp[1], pp[19]) ; PIX_SORT(pp[1], pp[10]) ; PIX_SORT(pp[11], pp[20]) ;\ -PIX_SORT(pp[2], pp[20]) ; PIX_SORT(pp[2], pp[11]) ; PIX_SORT(pp[12], pp[21]) ;\ -PIX_SORT(pp[3], pp[21]) ; PIX_SORT(pp[3], pp[12]) ; PIX_SORT(pp[13], pp[22]) ;\ -PIX_SORT(pp[4], pp[22]) ; PIX_SORT(pp[4], pp[13]) ; PIX_SORT(pp[14], pp[23]) ;\ -PIX_SORT(pp[5], pp[23]) ; PIX_SORT(pp[5], pp[14]) ; PIX_SORT(pp[15], pp[24]) ;\ -PIX_SORT(pp[6], pp[24]) ; PIX_SORT(pp[6], pp[15]) ; PIX_SORT(pp[7], pp[16]) ;\ -PIX_SORT(pp[7], pp[19]) ; PIX_SORT(pp[13], pp[21]) ; PIX_SORT(pp[15], pp[23]) ;\ -PIX_SORT(pp[7], pp[13]) ; PIX_SORT(pp[7], pp[15]) ; PIX_SORT(pp[1], pp[9]) ;\ -PIX_SORT(pp[3], pp[11]) ; PIX_SORT(pp[5], pp[17]) ; PIX_SORT(pp[11], pp[17]) ;\ -PIX_SORT(pp[9], pp[17]) ; PIX_SORT(pp[4], pp[10]) ; PIX_SORT(pp[6], pp[12]) ;\ -PIX_SORT(pp[7], pp[14]) ; PIX_SORT(pp[4], pp[6]) ; PIX_SORT(pp[4], pp[7]) ;\ -PIX_SORT(pp[12], pp[14]) ; PIX_SORT(pp[10], pp[14]) ; PIX_SORT(pp[6], pp[7]) ;\ -PIX_SORT(pp[10], pp[12]) ; PIX_SORT(pp[6], pp[10]) ; PIX_SORT(pp[6], pp[17]) ;\ -PIX_SORT(pp[12], pp[17]) ; PIX_SORT(pp[7], pp[17]) ; PIX_SORT(pp[7], pp[10]) ;\ -PIX_SORT(pp[12], pp[18]) ; PIX_SORT(pp[7], pp[12]) ; PIX_SORT(pp[10], pp[18]) ;\ -PIX_SORT(pp[12], pp[20]) ; PIX_SORT(pp[10], pp[20]) ; PIX_SORT(pp[10], pp[12]) ;\ -median=pp[12];} - -#define ELEM_FLOAT_SWAP(a,b) { register float t=(a);(a)=(b);(b)=t; } - namespace rtengine { @@ -117,135 +72,48 @@ namespace rtengine extern const Settings* settings; -// Median calculation using quicksort -float fq_sort2(float arr[], int n) +void ImProcFunctions::Median_Denoise(float **src, float **dst, const int width, const int height, const Median medianType, const int iterations, const int numThreads, float **buffer) { - int low = 0; - int high = n - 1; - int median = (low + high) / 2; + int border = 1; - for (;;) { - if (high <= low) { - return arr[median] ; + switch (medianType) { + case Median::TYPE_3X3_SOFT: + case Median::TYPE_3X3_STRONG: { + border = 1; + break; } - if (high == low + 1) { - if (arr[low] > arr[high]) { - ELEM_FLOAT_SWAP(arr[low], arr[high]) ; - } - - return arr[median] ; + case Median::TYPE_5X5_SOFT: { + border = 2; + break; } - int middle = (low + high) / 2; - - if (arr[middle] > arr[high]) { - ELEM_FLOAT_SWAP(arr[middle], arr[high]) ; + case Median::TYPE_5X5_STRONG: { + border = 2; + break; } - if (arr[low] > arr[high]) { - ELEM_FLOAT_SWAP(arr[low], arr[high]) ; + case Median::TYPE_7X7: { + border = 3; + break; } - if (arr[middle] > arr[low]) { - ELEM_FLOAT_SWAP(arr[middle], arr[low]) ; - } - - ELEM_FLOAT_SWAP(arr[middle], arr[low + 1]) ; - int ll = low + 1; - int hh = high; - - for (;;) { - do { - ll++; - } while (arr[low] > arr[ll]) ; - - do { - hh--; - } while (arr[hh] > arr[low]) ; - - if (hh < ll) { - break; - } - - ELEM_FLOAT_SWAP(arr[ll], arr[hh]) ; - } - - ELEM_FLOAT_SWAP(arr[low], arr[hh]) ; - - if (hh <= median) { - low = ll; - } - - if (hh >= median) { - high = hh - 1; + case Median::TYPE_9X9: { + border = 4; + break; } } -} -float media(float *elements, int N) -{ - - // Order elements (only half of them) - for (int i = 0; i < (N >> 1) + 1; ++i) { - // Find position of minimum element - int min = i; - - for (int j = i + 1; j < N; ++j) - if (elements[j] < elements[min]) { - min = j; - } - - // Put found minimum element in its place - float temp = elements[i]; - elements[i] = elements[min]; - elements[min] = temp; - } - - // Get result - the middle element - return elements[N >> 1]; -} - -void ImProcFunctions::Median_Denoise( float **src, float **dst, const int width, const int height, const mediantype medianType, const int iterations, const int numThreads, float **buffer) -{ - int border = 1, numElements, middleElement; - - switch(medianType) { - case MED_3X3SOFT: - case MED_3X3STRONG: - border = 1; - break; - - case MED_5X5SOFT: - border = 2; - break; - - case MED_5X5STRONG: - border = 2; - break; - - case MED_7X7: - border = 3; - numElements = 49; - middleElement = 24; - break; - - default: // includes MED_9X9 - border = 4; - numElements = 81; - middleElement = 40; - } - - float **allocBuffer = NULL; + float **allocBuffer = nullptr; float **medBuffer[2]; medBuffer[0] = src; // we need a buffer if src == dst or if (src != dst && iterations > 1) - if(src == dst || (src != dst && iterations > 1)) { - if(buffer == NULL) { // we didn't get a buufer => create one + if (src == dst || (src != dst && iterations > 1)) { + if (buffer == nullptr) { // we didn't get a buufer => create one allocBuffer = new float*[height]; - for (int i = 0; i < height; i++) { + for (int i = 0; i < height; ++i) { allocBuffer[i] = new float[width]; } @@ -260,151 +128,252 @@ void ImProcFunctions::Median_Denoise( float **src, float **dst, const int width, float ** medianIn, ** medianOut; int BufferIndex = 0; - for(int iteration = 1; iteration <= iterations; iteration++) { + for (int iteration = 1; iteration <= iterations; ++iteration) { medianIn = medBuffer[BufferIndex]; medianOut = medBuffer[BufferIndex ^ 1]; - if(iteration == 1) { // upper border - for (int i = 0; i < border; i++) - for (int j = 0; j < width; j++) { - medianOut[i][j] = medianIn[i][j]; - } - } - -#ifdef _OPENMP - #pragma omp parallel for num_threads(numThreads) if(numThreads>1) -#endif - - for (int i = border; i < height - border; i++) { - if(medianType == MED_3X3SOFT) { - float pp[5], temp; - int j; - - for (j = 0; j < border; j++) { - medianOut[i][j] = medianIn[i][j]; - } - - for (; j < width - border; j++) { - med2(medianIn[i][j] , medianIn[i - 1][j], medianIn[i + 1][j] , medianIn[i][j + 1], medianIn[i][j - 1], medianOut[i][j]); - } - - for(; j < width; j++) { - medianOut[i][j] = medianIn[i][j]; - } - } else if(medianType == MED_3X3STRONG) { - float pp[9], temp; - int j; - - for (j = 0; j < border; j++) { - medianOut[i][j] = medianIn[i][j]; - } - - for (; j < width - border; j++) { - med3(medianIn[i][j] , medianIn[i - 1][j], medianIn[i + 1][j] , medianIn[i][j + 1], medianIn[i][j - 1], medianIn[i - 1][j - 1], medianIn[i - 1][j + 1], medianIn[i + 1][j - 1], medianIn[i + 1][j + 1], medianOut[i][j]); - } - - for(; j < width; j++) { - medianOut[i][j] = medianIn[i][j]; - } - } else if(medianType == MED_5X5SOFT) { - float pp[13]; - int j; - - for (j = 0; j < border; j++) { - medianOut[i][j] = medianIn[i][j]; - } - - for (; j < width - border; j++) { - pp[0] = medianIn[i][j]; - pp[1] = medianIn[i - 1][j]; - pp[2] = medianIn[i + 1][j]; - pp[3] = medianIn[i][j + 1]; - pp[4] = medianIn[i][j - 1]; - pp[5] = medianIn[i - 1][j - 1]; - pp[6] = medianIn[i - 1][j + 1]; - pp[7] = medianIn[i + 1][j - 1]; - pp[8] = medianIn[i + 1][j + 1]; - pp[9] = medianIn[i + 2][j]; - pp[10] = medianIn[i - 2][j]; - pp[11] = medianIn[i][j + 2]; - pp[12] = medianIn[i][j - 2]; - fq_sort2(pp, 13); - medianOut[i][j] = pp[6]; - } - - for(; j < width; j++) { - medianOut[i][j] = medianIn[i][j]; - } - } else if(medianType == MED_5X5STRONG) { - float pp[25], temp; - int j; - - for (j = 0; j < border; j++) { - medianOut[i][j] = medianIn[i][j]; - } - - for (; j < width - border; j++) { - med5(medianIn[i][j], medianIn[i - 1][j], medianIn[i + 1][j], medianIn[i][j + 1], medianIn[i][j - 1], medianIn[i - 1][j - 1], medianIn[i - 1][j + 1], medianIn[i + 1][j - 1], medianIn[i + 1][j + 1], - medianIn[i - 2][j], medianIn[i + 2][j], medianIn[i][j + 2], medianIn[i][j - 2], medianIn[i - 2][j - 2], medianIn[i - 2][j + 2], medianIn[i + 2][j - 2], medianIn[i + 2][j + 2], - medianIn[i - 2][j + 1], medianIn[i + 2][j + 1], medianIn[i - 1][j + 2], medianIn[i - 1][j - 2], medianIn[i - 2][j - 1], medianIn[i + 2][j - 1], medianIn[i + 1][j + 2], medianIn[i + 1][j - 2], - medianOut[i][j]); - } - - for(; j < width; j++) { - medianOut[i][j] = medianIn[i][j]; - } - } else {// includes MED_7X7 and MED_9X9 - float pp[81]; - int j; - - for (j = 0; j < border; j++) { - medianOut[i][j] = medianIn[i][j]; - } - - for (; j < width - border; j++) { - int kk = 0; - - for (int ii = -border; ii <= border; ii++) { - for (int jj = -border; jj <= border; jj++) { - kk++; - pp[kk] = medianIn[i + ii][j + jj]; - } - } - - fq_sort2(pp, numElements); - medianOut[i][j] = pp[middleElement]; - } - - for(; j < width; j++) { + if (iteration == 1) { // upper border + for (int i = 0; i < border; ++i) { + for (int j = 0; j < width; ++j) { medianOut[i][j] = medianIn[i][j]; } } } - if(iteration == 1) { // lower border - for (int i = height - border; i < height; i++) - for (int j = 0; j < width; j++) { +#ifdef _OPENMP + #pragma omp parallel for num_threads(numThreads) if (numThreads>1) schedule(dynamic,16) +#endif + + for (int i = border; i < height - border; ++i) { + int j = 0; + + for (; j < border; ++j) { + medianOut[i][j] = medianIn[i][j]; + } + + switch (medianType) { + case Median::TYPE_3X3_SOFT: { + for (; j < width - border; ++j) { + medianOut[i][j] = median( + medianIn[i - 1][j], + medianIn[i][j - 1], + medianIn[i][j], + medianIn[i][j + 1], + medianIn[i + 1][j] + ); + } + + break; + } + + case Median::TYPE_3X3_STRONG: { + for (; j < width - border; ++j) { + medianOut[i][j] = median( + medianIn[i - 1][j - 1], + medianIn[i - 1][j], + medianIn[i - 1][j + 1], + medianIn[i][j - 1], + medianIn[i][j], + medianIn[i][j + 1], + medianIn[i + 1][j - 1], + medianIn[i + 1][j], + medianIn[i + 1][j + 1] + ); + } + + break; + } + + case Median::TYPE_5X5_SOFT: { + for (; j < width - border; ++j) { + medianOut[i][j] = median( + medianIn[i - 2][j], + medianIn[i - 1][j - 1], + medianIn[i - 1][j], + medianIn[i - 1][j + 1], + medianIn[i][j - 2], + medianIn[i][j - 1], + medianIn[i][j], + medianIn[i][j + 1], + medianIn[i][j + 2], + medianIn[i + 1][j - 1], + medianIn[i + 1][j], + medianIn[i + 1][j + 1], + medianIn[i + 2][j] + ); + } + + break; + } + + case Median::TYPE_5X5_STRONG: { +#ifdef __SSE2__ + + for (; j < width - border - 3; j += 4) { + STVFU( + medianOut[i][j], + median( + LVFU(medianIn[i - 2][j - 2]), + LVFU(medianIn[i - 2][j - 1]), + LVFU(medianIn[i - 2][j]), + LVFU(medianIn[i - 2][j + 1]), + LVFU(medianIn[i - 2][j + 2]), + LVFU(medianIn[i - 1][j - 2]), + LVFU(medianIn[i - 1][j - 1]), + LVFU(medianIn[i - 1][j]), + LVFU(medianIn[i - 1][j + 1]), + LVFU(medianIn[i - 1][j + 2]), + LVFU(medianIn[i][j - 2]), + LVFU(medianIn[i][j - 1]), + LVFU(medianIn[i][j]), + LVFU(medianIn[i][j + 1]), + LVFU(medianIn[i][j + 2]), + LVFU(medianIn[i + 1][j - 2]), + LVFU(medianIn[i + 1][j - 1]), + LVFU(medianIn[i + 1][j]), + LVFU(medianIn[i + 1][j + 1]), + LVFU(medianIn[i + 1][j + 2]), + LVFU(medianIn[i + 2][j - 2]), + LVFU(medianIn[i + 2][j - 1]), + LVFU(medianIn[i + 2][j]), + LVFU(medianIn[i + 2][j + 1]), + LVFU(medianIn[i + 2][j + 2]) + ) + ); + } + +#endif + + for (; j < width - border; ++j) { + medianOut[i][j] = median( + medianIn[i - 2][j - 2], + medianIn[i - 2][j - 1], + medianIn[i - 2][j], + medianIn[i - 2][j + 1], + medianIn[i - 2][j + 2], + medianIn[i - 1][j - 2], + medianIn[i - 1][j - 1], + medianIn[i - 1][j], + medianIn[i - 1][j + 1], + medianIn[i - 1][j + 2], + medianIn[i][j - 2], + medianIn[i][j - 1], + medianIn[i][j], + medianIn[i][j + 1], + medianIn[i][j + 2], + medianIn[i + 1][j - 2], + medianIn[i + 1][j - 1], + medianIn[i + 1][j], + medianIn[i + 1][j + 1], + medianIn[i + 1][j + 2], + medianIn[i + 2][j - 2], + medianIn[i + 2][j - 1], + medianIn[i + 2][j], + medianIn[i + 2][j + 1], + medianIn[i + 2][j + 2] + ); + } + + break; + } + + case Median::TYPE_7X7: { +#ifdef __SSE2__ + std::array vpp ALIGNED16; + + for (; j < width - border - 3; j += 4) { + for (int kk = 0, ii = -border; ii <= border; ++ii) { + for (int jj = -border; jj <= border; ++jj, ++kk) { + vpp[kk] = LVFU(medianIn[i + ii][j + jj]); + } + } + + STVFU(medianOut[i][j], median(vpp)); + } + +#endif + + std::array pp; + + for (; j < width - border; ++j) { + for (int kk = 0, ii = -border; ii <= border; ++ii) { + for (int jj = -border; jj <= border; ++jj, ++kk) { + pp[kk] = medianIn[i + ii][j + jj]; + } + } + + medianOut[i][j] = median(pp); + } + + break; + } + + case Median::TYPE_9X9: { +#ifdef __SSE2__ + std::array vpp ALIGNED16; + + for (; j < width - border - 3; j += 4) { + for (int kk = 0, ii = -border; ii <= border; ++ii) { + for (int jj = -border; jj <= border; ++jj, ++kk) { + vpp[kk] = LVFU(medianIn[i + ii][j + jj]); + } + } + + STVFU(medianOut[i][j], median(vpp)); + } + +#endif + + std::array pp; + + for (; j < width - border; ++j) { + for (int kk = 0, ii = -border; ii <= border; ++ii) { + for (int jj = -border; jj <= border; ++jj, ++kk) { + pp[kk] = medianIn[i + ii][j + jj]; + } + } + + medianOut[i][j] = median(pp); + } + + for (; j < width; ++j) { + medianOut[i][j] = medianIn[i][j]; + } + + break; + } + } + + for (; j < width; ++j) { + medianOut[i][j] = medianIn[i][j]; + } + } + + if (iteration == 1) { // lower border + for (int i = height - border; i < height; ++i) { + for (int j = 0; j < width; ++j) { medianOut[i][j] = medianIn[i][j]; } + } } BufferIndex ^= 1; // swap buffers } - if(medianOut != dst) { + if (medianOut != dst) { #ifdef _OPENMP - #pragma omp parallel for num_threads(numThreads) if(numThreads>1) + #pragma omp parallel for num_threads(numThreads) if (numThreads>1) #endif - for(int i = border; i < height - border; i++ ) { - for(int j = border; j < width - border; j++) { + for (int i = border; i < height - border; ++i) { + for (int j = border; j < width - border; ++j) { dst[i][j] = medianOut[i][j]; } } } - if(allocBuffer != NULL) { // we allocated memory, so let's free it now - for (int i = 0; i < height; i++) { + if (allocBuffer != nullptr) { // we allocated memory, so let's free it now + for (int i = 0; i < height; ++i) { delete[] allocBuffer[i]; } @@ -412,18 +381,18 @@ void ImProcFunctions::Median_Denoise( float **src, float **dst, const int width, } } -void ImProcFunctions::Tile_calc (int tilesize, int overlap, int kall, int imwidth, int imheight, int &numtiles_W, int &numtiles_H, int &tilewidth, int &tileheight, int &tileWskip, int &tileHskip) +void ImProcFunctions::Tile_calc(int tilesize, int overlap, int kall, int imwidth, int imheight, int &numtiles_W, int &numtiles_H, int &tilewidth, int &tileheight, int &tileWskip, int &tileHskip) { - if(kall == 2) { + if (kall == 2) { if (imwidth < tilesize) { numtiles_W = 1; tileWskip = imwidth; tilewidth = imwidth; } else { - numtiles_W = ceil(((float)(imwidth)) / (tilesize - overlap)); - tilewidth = ceil(((float)(imwidth)) / (numtiles_W)) + overlap; + numtiles_W = ceil((static_cast(imwidth)) / (tilesize - overlap)); + tilewidth = ceil((static_cast(imwidth)) / (numtiles_W)) + overlap; tilewidth += (tilewidth & 1); tileWskip = tilewidth - overlap; } @@ -433,14 +402,14 @@ void ImProcFunctions::Tile_calc (int tilesize, int overlap, int kall, int imwidt tileHskip = imheight; tileheight = imheight; } else { - numtiles_H = ceil(((float)(imheight)) / (tilesize - overlap)); - tileheight = ceil(((float)(imheight)) / (numtiles_H)) + overlap; + numtiles_H = ceil((static_cast(imheight)) / (tilesize - overlap)); + tileheight = ceil((static_cast(imheight)) / (numtiles_H)) + overlap; tileheight += (tileheight & 1); tileHskip = tileheight - overlap; } } - if(kall == 0) { + if (kall == 0) { numtiles_W = 1; tileWskip = imwidth; tilewidth = imwidth; @@ -464,13 +433,13 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef //#endif if (dnparams.luma == 0 && dnparams.chroma == 0 && !dnparams.median && !noiseLCurve && !noiseCCurve) { //nothing to do; copy src to dst or do nothing in case src == dst - if(src != dst) { + if (src != dst) { src->copyData(dst); } - if(calclum) { + if (calclum) { delete calclum; - calclum = NULL; + calclum = nullptr; } return; @@ -480,9 +449,9 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef MyMutex::MyLock lock(FftwMutex); const nrquality nrQuality = (dnparams.smethod == "shal") ? QUALITY_STANDARD : QUALITY_HIGH;//shrink method - const float qhighFactor = (nrQuality == QUALITY_HIGH) ? 1.f / (float) settings->nrhigh : 1.0f; - const bool useNoiseCCurve = (noiseCCurve && noiseCCurve.getSum() > 5.f ); - const bool useNoiseLCurve = (noiseLCurve && noiseLCurve.getSum() >= 7.f ); + const float qhighFactor = (nrQuality == QUALITY_HIGH) ? 1.f / static_cast( settings->nrhigh) : 1.0f; + const bool useNoiseCCurve = (noiseCCurve && noiseCCurve.getSum() > 5.f); + const bool useNoiseLCurve = (noiseLCurve && noiseLCurve.getSum() >= 7.f); const bool autoch = (settings->leveldnautsimpl == 1 && (dnparams.Cmethod == "AUT" || dnparams.Cmethod == "PRE")) || (settings->leveldnautsimpl == 0 && (dnparams.C2method == "AUTO" || dnparams.C2method == "PREV")); float** lumcalc; @@ -493,39 +462,39 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef bool ponder = false; float ponderCC = 1.f; - if(settings->leveldnautsimpl == 1 && params->dirpyrDenoise.Cmethod == "PON") { + if (settings->leveldnautsimpl == 1 && params->dirpyrDenoise.Cmethod == "PON") { ponder = true; ponderCC = 0.5f; } - if(settings->leveldnautsimpl == 1 && params->dirpyrDenoise.Cmethod == "PRE") { + if (settings->leveldnautsimpl == 1 && params->dirpyrDenoise.Cmethod == "PRE") { ponderCC = 0.5f; } - if(settings->leveldnautsimpl == 0 && params->dirpyrDenoise.Cmethod == "PREV") { + if (settings->leveldnautsimpl == 0 && params->dirpyrDenoise.Cmethod == "PREV") { ponderCC = 0.5f; } int metchoice = 0; - if(dnparams.methodmed == "Lonly") { + if (dnparams.methodmed == "Lonly") { metchoice = 1; - } else if(dnparams.methodmed == "Lab") { + } else if (dnparams.methodmed == "Lab") { metchoice = 2; - } else if(dnparams.methodmed == "ab") { + } else if (dnparams.methodmed == "ab") { metchoice = 3; - } else if(dnparams.methodmed == "Lpab") { + } else if (dnparams.methodmed == "Lpab") { metchoice = 4; } const bool denoiseMethodRgb = (dnparams.dmethod == "RGB"); // init luma noisevarL - const float noiseluma = (float) dnparams.luma; - const float noisevarL = (useNoiseLCurve && (denoiseMethodRgb || !isRAW)) ? (float) (SQR(((noiseluma + 1.0) / 125.0) * (10. + (noiseluma + 1.0) / 25.0))) : (float) (SQR((noiseluma / 125.0) * (1.0 + noiseluma / 25.0))); + const float noiseluma = static_cast( dnparams.luma); + const float noisevarL = (useNoiseLCurve && (denoiseMethodRgb || !isRAW)) ? static_cast (SQR(((noiseluma + 1.0) / 125.0) * (10. + (noiseluma + 1.0) / 25.0))) : static_cast (SQR((noiseluma / 125.0) * (1.0 + noiseluma / 25.0))); const bool denoiseLuminance = (noisevarL > 0.00001f); //printf("NL=%f \n",noisevarL); - if(useNoiseLCurve || useNoiseCCurve) { + if (useNoiseLCurve || useNoiseCCurve) { int hei = calclum->height; int wid = calclum->width; TMatrix wprofi = iccStore->workingSpaceMatrix (params->icm.working); @@ -538,20 +507,20 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef lumcalcBuffer = new float[hei * wid]; lumcalc = new float*[(hei)]; - for (int i = 0; i < hei; i++) { + for (int i = 0; i < hei; ++i) { lumcalc[i] = lumcalcBuffer + (i * wid); } ccalcBuffer = new float[hei * wid]; ccalc = new float*[(hei)]; - for (int i = 0; i < hei; i++) { + for (int i = 0; i < hei; ++i) { ccalc[i] = ccalcBuffer + (i * wid); } float cn100Precalc; - if(useNoiseCCurve) { + if (useNoiseCCurve) { cn100Precalc = SQR(1.f + ponderCC * (4.f * noiseCCurve[100.f / 60.f])); } @@ -559,8 +528,8 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef #pragma omp parallel for schedule(dynamic,16) #endif - for(int ii = 0; ii < hei; ii++) { - for(int jj = 0; jj < wid; jj++) { + for (int ii = 0; ii < hei; ++ii) { + for (int jj = 0; jj < wid; ++jj) { float LLum, AAum, BBum; float RL = calclum->r(ii, jj); @@ -571,14 +540,14 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef Color::rgbxyz(RL, GL, BL, XL, YL, ZL, wpi); Color::XYZ2Lab(XL, YL, ZL, LLum, AAum, BBum); - if(useNoiseLCurve) { + if (useNoiseLCurve) { float epsi = 0.01f; - if(LLum < 2.f) { + if (LLum < 2.f) { LLum = 2.f; //avoid divided by zero } - if(LLum > 32768.f) { + if (LLum > 32768.f) { LLum = 32768.f; // not strictly necessary } @@ -588,10 +557,10 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef lumcalc[ii][jj] = SQR((kinterm / 125.f) * (1.f + kinterm / 25.f)); } - if(useNoiseCCurve) { + if (useNoiseCCurve) { float cN = sqrtf(SQR(AAum) + SQR(BBum)); - if(cN > 100) { + if (cN > 100) { ccalc[ii][jj] = SQR(1.f + ponderCC * (4.f * noiseCCurve[cN / 60.f])); } else { ccalc[ii][jj] = cn100Precalc; @@ -601,35 +570,35 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef } delete calclum; - calclum = NULL; + calclum = nullptr; } const short int imheight = src->height, imwidth = src->width; - if (dnparams.luma != 0 || dnparams.chroma != 0 || dnparams.methodmed == "Lab" || dnparams.methodmed == "Lonly" ) { + if (dnparams.luma != 0 || dnparams.chroma != 0 || dnparams.methodmed == "Lab" || dnparams.methodmed == "Lonly") { // gamma transform for input data float gam = dnparams.gamma; float gamthresh = 0.001f; - if(!isRAW) {//reduce gamma under 1 for Lab mode ==> TIF and JPG - if(gam < 1.9f) { + if (!isRAW) {//reduce gamma under 1 for Lab mode ==> TIF and JPG + if (gam < 1.9f) { gam = 1.f - (1.9f - gam) / 3.f; //minimum gamma 0.7 } else if (gam >= 1.9f && gam <= 3.f) { gam = (1.4f / 1.1f) * gam - 1.41818f; } } - float gamslope = exp(log((double)gamthresh) / gam) / gamthresh; + float gamslope = exp(log(static_cast(gamthresh)) / gam) / gamthresh; LUTf gamcurve(65536, LUT_CLIP_BELOW); - if(denoiseMethodRgb) { - for (int i = 0; i < 65536; i++) { - gamcurve[i] = (Color::gamma((double)i / 65535.0, gam, gamthresh, gamslope, 1.0, 0.0)) * 32768.0f; + if (denoiseMethodRgb) { + for (int i = 0; i < 65536; ++i) { + gamcurve[i] = (Color::gamma(static_cast(i) / 65535.0, gam, gamthresh, gamslope, 1.0, 0.0)) * 32768.0f; } } else { - for (int i = 0; i < 65536; i++) { - gamcurve[i] = (Color::gamman((double)i / 65535.0, gam)) * 32768.0f; + for (int i = 0; i < 65536; ++i) { + gamcurve[i] = (Color::gamman(static_cast(i) / 65535.0, gam)) * 32768.0f; } } @@ -640,20 +609,20 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef LUTf igamcurve(65536, LUT_CLIP_BELOW); - if(denoiseMethodRgb) { - for (int i = 0; i < 65536; i++) { - igamcurve[i] = (Color::gamma((float)i / 32768.0f, igam, igamthresh, igamslope, 1.0, 0.0) * 65535.0f); + if (denoiseMethodRgb) { + for (int i = 0; i < 65536; ++i) { + igamcurve[i] = (Color::gamma(static_cast(i) / 32768.0f, igam, igamthresh, igamslope, 1.0, 0.0) * 65535.0f); } } else { - for (int i = 0; i < 65536; i++) { - igamcurve[i] = (Color::gamman((float)i / 32768.0f, igam) * 65535.0f); + for (int i = 0; i < 65536; ++i) { + igamcurve[i] = (Color::gamman(static_cast(i) / 32768.0f, igam) * 65535.0f); } } const float gain = pow (2.0f, float(expcomp)); - float noisevar_Ldetail = SQR((float)(SQR(100. - dnparams.Ldetail) + 50.*(100. - dnparams.Ldetail)) * TS * 0.5f); + float noisevar_Ldetail = SQR(static_cast(SQR(100. - dnparams.Ldetail) + 50.*(100. - dnparams.Ldetail)) * TS * 0.5f); - if(settings->verbose) { + if (settings->verbose) { printf("Denoise Lab=%i\n", settings->denoiselabgamma); } @@ -667,34 +636,34 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef LUTf *denoiseigamtab; switch(settings->denoiselabgamma) { - case 0: - denoisegamtab = &(Color::gammatab_26_11); - denoiseigamtab = &(Color::igammatab_26_11); - break; + case 0: + denoisegamtab = &(Color::gammatab_26_11); + denoiseigamtab = &(Color::igammatab_26_11); + break; - case 1: - denoisegamtab = &(Color::gammatab_4); - denoiseigamtab = &(Color::igammatab_4); - break; + case 1: + denoisegamtab = &(Color::gammatab_4); + denoiseigamtab = &(Color::igammatab_4); + break; - default: - denoisegamtab = &(Color::gammatab_55); - denoiseigamtab = &(Color::igammatab_55); - break; + default: + denoisegamtab = &(Color::gammatab_55); + denoiseigamtab = &(Color::igammatab_55); + break; } array2D tilemask_in(TS, TS); array2D tilemask_out(TS, TS); - if(denoiseLuminance) { + if (denoiseLuminance) { const int border = MAX(2, TS / 16); - for (int i = 0; i < TS; i++) { + for (int i = 0; i < TS; ++i) { float i1 = abs((i > TS / 2 ? i - TS + 1 : i)); float vmask = (i1 < border ? SQR(sin((M_PI * i1) / (2 * border))) : 1.0f); float vmask2 = (i1 < 2 * border ? SQR(sin((M_PI * i1) / (2 * border))) : 1.0f); - for (int j = 0; j < TS; j++) { + for (int j = 0; j < TS; ++j) { float j1 = abs((j > TS / 2 ? j - TS + 1 : j)); tilemask_in[i][j] = (vmask * (j1 < border ? SQR(sin((M_PI * j1) / (2 * border))) : 1.0f)) + epsilon; tilemask_out[i][j] = (vmask2 * (j1 < 2 * border ? SQR(sin((M_PI * j1) / (2 * border))) : 1.0f)) + epsilon; @@ -706,28 +675,28 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef int tilesize; int overlap; - if(settings->leveldnti == 0) { + if (settings->leveldnti == 0) { tilesize = 1024; overlap = 128; } - if(settings->leveldnti == 1) { + if (settings->leveldnti == 1) { tilesize = 768; overlap = 96; } int numTries = 0; - if(ponder) { + if (ponder) { printf("Tiled denoise processing caused by Automatic Multizone mode\n"); } bool memoryAllocationFailed = false; do { - numTries++; + ++numTries; - if(numTries == 2) { + if (numTries == 2) { printf("1st denoise pass failed due to insufficient memory, starting 2nd (tiled) pass now...\n"); } @@ -740,7 +709,7 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef //output buffer Imagefloat * dsttmp; - if(numtiles == 1) { + if (numtiles == 1) { dsttmp = dst; } else { dsttmp = new Imagefloat(imwidth, imheight); @@ -748,12 +717,13 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef #pragma omp parallel for #endif - for(int i = 0; i < imheight; i++) - for(int j = 0; j < imwidth; j++) { + for (int i = 0; i < imheight; ++i) { + for (int j = 0; j < imwidth; ++j) { dsttmp->r(i, j) = 0.f; dsttmp->g(i, j) = 0.f; dsttmp->b(i, j) = 0.f; } + } } //now we have tile dimensions, overlaps @@ -763,17 +733,17 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef // outside the parallel region and use them inside the parallel region. // calculate max size of numblox_W. - int max_numblox_W = ceil(((float)(MIN(imwidth, tilewidth))) / (offset)) + 2 * blkrad; + int max_numblox_W = ceil((static_cast(MIN(imwidth, tilewidth))) / (offset)) + 2 * blkrad; // calculate min size of numblox_W. - int min_numblox_W = ceil(((float)((MIN(imwidth, ((numtiles_W - 1) * tileWskip) + tilewidth) ) - ((numtiles_W - 1) * tileWskip))) / (offset)) + 2 * blkrad; + int min_numblox_W = ceil((static_cast((MIN(imwidth, ((numtiles_W - 1) * tileWskip) + tilewidth)) - ((numtiles_W - 1) * tileWskip))) / (offset)) + 2 * blkrad; // these are needed only for creation of the plans and will be freed before entering the parallel loop fftwf_plan plan_forward_blox[2]; fftwf_plan plan_backward_blox[2]; - if(denoiseLuminance) { - float *Lbloxtmp = (float*) fftwf_malloc(max_numblox_W * TS * TS * sizeof (float)); - float *fLbloxtmp = (float*) fftwf_malloc(max_numblox_W * TS * TS * sizeof (float)); + if (denoiseLuminance) { + float *Lbloxtmp = reinterpret_cast( fftwf_malloc(max_numblox_W * TS * TS * sizeof (float))); + float *fLbloxtmp = reinterpret_cast( fftwf_malloc(max_numblox_W * TS * TS * sizeof (float))); int nfwd[2] = {TS, TS}; @@ -782,12 +752,12 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef fftw_r2r_kind bwdkind[2] = {FFTW_REDFT01, FFTW_REDFT01}; // Creating the plans with FFTW_MEASURE instead of FFTW_ESTIMATE speeds up the execute a bit - plan_forward_blox[0] = fftwf_plan_many_r2r(2, nfwd, max_numblox_W, Lbloxtmp, NULL, 1, TS * TS, fLbloxtmp, NULL, 1, TS * TS, fwdkind, FFTW_MEASURE || FFTW_DESTROY_INPUT ); - plan_backward_blox[0] = fftwf_plan_many_r2r(2, nfwd, max_numblox_W, fLbloxtmp, NULL, 1, TS * TS, Lbloxtmp, NULL, 1, TS * TS, bwdkind, FFTW_MEASURE || FFTW_DESTROY_INPUT ); - plan_forward_blox[1] = fftwf_plan_many_r2r(2, nfwd, min_numblox_W, Lbloxtmp, NULL, 1, TS * TS, fLbloxtmp, NULL, 1, TS * TS, fwdkind, FFTW_MEASURE || FFTW_DESTROY_INPUT ); - plan_backward_blox[1] = fftwf_plan_many_r2r(2, nfwd, min_numblox_W, fLbloxtmp, NULL, 1, TS * TS, Lbloxtmp, NULL, 1, TS * TS, bwdkind, FFTW_MEASURE || FFTW_DESTROY_INPUT ); - fftwf_free ( Lbloxtmp ); - fftwf_free ( fLbloxtmp ); + plan_forward_blox[0] = fftwf_plan_many_r2r(2, nfwd, max_numblox_W, Lbloxtmp, nullptr, 1, TS * TS, fLbloxtmp, nullptr, 1, TS * TS, fwdkind, FFTW_MEASURE || FFTW_DESTROY_INPUT ); + plan_backward_blox[0] = fftwf_plan_many_r2r(2, nfwd, max_numblox_W, fLbloxtmp, nullptr, 1, TS * TS, Lbloxtmp, nullptr, 1, TS * TS, bwdkind, FFTW_MEASURE || FFTW_DESTROY_INPUT ); + plan_forward_blox[1] = fftwf_plan_many_r2r(2, nfwd, min_numblox_W, Lbloxtmp, nullptr, 1, TS * TS, fLbloxtmp, nullptr, 1, TS * TS, fwdkind, FFTW_MEASURE || FFTW_DESTROY_INPUT ); + plan_backward_blox[1] = fftwf_plan_many_r2r(2, nfwd, min_numblox_W, fLbloxtmp, nullptr, 1, TS * TS, Lbloxtmp, nullptr, 1, TS * TS, bwdkind, FFTW_MEASURE || FFTW_DESTROY_INPUT ); + fftwf_free (Lbloxtmp); + fftwf_free (fLbloxtmp); } #ifndef _OPENMP @@ -796,7 +766,7 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef // Calculate number of tiles. If less than omp_get_max_threads(), then limit num_threads to number of tiles int numthreads = MIN(numtiles, omp_get_max_threads()); - if(options.rgbDenoiseThreadLimit > 0) { + if (options.rgbDenoiseThreadLimit > 0) { numthreads = MIN(numthreads, options.rgbDenoiseThreadLimit); } @@ -804,20 +774,20 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef denoiseNestedLevels = omp_get_max_threads() / numthreads; bool oldNested = omp_get_nested(); - if(denoiseNestedLevels < 2) { + if (denoiseNestedLevels < 2) { denoiseNestedLevels = 1; } else { omp_set_nested(true); } - if(options.rgbDenoiseThreadLimit > 0) + if (options.rgbDenoiseThreadLimit > 0) while(denoiseNestedLevels * numthreads > options.rgbDenoiseThreadLimit) { denoiseNestedLevels--; } #endif - if(settings->verbose) { + if (settings->verbose) { printf("RGB_denoise uses %d main thread(s) and up to %d nested thread(s) for each main thread\n", numthreads, denoiseNestedLevels); } @@ -825,11 +795,12 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef float *LbloxArray[denoiseNestedLevels * numthreads]; float *fLbloxArray[denoiseNestedLevels * numthreads]; - if(numtiles > 1 && denoiseLuminance) - for(int i = 0; i < denoiseNestedLevels * numthreads; i++) { - LbloxArray[i] = (float*) fftwf_malloc(max_numblox_W * TS * TS * sizeof(float)); - fLbloxArray[i] = (float*) fftwf_malloc(max_numblox_W * TS * TS * sizeof(float)); + if (numtiles > 1 && denoiseLuminance) { + for (int i = 0; i < denoiseNestedLevels * numthreads; ++i) { + LbloxArray[i] = reinterpret_cast( fftwf_malloc(max_numblox_W * TS * TS * sizeof(float))); + fLbloxArray[i] = reinterpret_cast( fftwf_malloc(max_numblox_W * TS * TS * sizeof(float))); } + } TMatrix wiprof = iccStore->workingSpaceInverseMatrix (params->icm.working); //inverse matrix user select @@ -850,14 +821,14 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef // begin tile processing of image #ifdef _OPENMP - #pragma omp parallel num_threads(numthreads) if(numthreads>1) + #pragma omp parallel num_threads(numthreads) if (numthreads>1) #endif { int pos; float* noisevarlum; float* noisevarchrom; - if(numtiles == 1 && isRAW && (useNoiseCCurve || useNoiseLCurve)) { + if (numtiles == 1 && isRAW && (useNoiseCCurve || useNoiseLCurve)) { noisevarlum = lumcalcBuffer; noisevarchrom = ccalcBuffer; } else { @@ -879,28 +850,28 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef int height = tilebottom - tiletop; int width2 = (width + 1) / 2; float realred, realblue; - float interm_med = (float) dnparams.chroma / 10.0; + float interm_med = static_cast( dnparams.chroma) / 10.0; float intermred, intermblue; - if(dnparams.redchro > 0.) { + if (dnparams.redchro > 0.) { intermred = (dnparams.redchro / 10.); } else { - intermred = (float) dnparams.redchro / 7.0; //increase slower than linear for more sensit + intermred = static_cast( dnparams.redchro) / 7.0; //increase slower than linear for more sensit } - if(dnparams.bluechro > 0.) { + if (dnparams.bluechro > 0.) { intermblue = (dnparams.bluechro / 10.); } else { - intermblue = (float) dnparams.bluechro / 7.0; //increase slower than linear for more sensit + intermblue = static_cast( dnparams.bluechro) / 7.0; //increase slower than linear for more sensit } - if(ponder && kall == 2) { + if (ponder && kall == 2) { interm_med = ch_M[pos] / 10.f; intermred = max_r[pos] / 10.f; intermblue = max_b[pos] / 10.f; } - if(ponder && kall == 0) { + if (ponder && kall == 0) { interm_med = 0.01f; intermred = 0.f; intermblue = 0.f; @@ -931,16 +902,16 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef if (isRAW) {//image is raw; use channel differences for chroma channels - if(!denoiseMethodRgb) { //lab mode + if (!denoiseMethodRgb) { //lab mode //modification Jacques feb 2013 and july 2014 #ifdef _RT_NESTED_OPENMP - #pragma omp parallel for num_threads(denoiseNestedLevels) if(denoiseNestedLevels>1) + #pragma omp parallel for num_threads(denoiseNestedLevels) if (denoiseNestedLevels>1) #endif - for (int i = tiletop; i < tilebottom; i++) { + for (int i = tiletop; i < tilebottom; ++i) { int i1 = i - tiletop; - for (int j = tileleft; j < tileright; j++) { + for (int j = tileleft; j < tileright; ++j) { int j1 = j - tileleft; float R_ = gain * src->r(i, j); float G_ = gain * src->g(i, j); @@ -967,8 +938,8 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef labdn->a[i1][j1] = a; labdn->b[i1][j1] = b; - if(((i1 | j1) & 1) == 0) { - if(numTries == 1) { + if (((i1 | j1) & 1) == 0) { + if (numTries == 1) { noisevarlum[(i1 >> 1)*width2 + (j1 >> 1)] = useNoiseLCurve ? lumcalc[i >> 1][j >> 1] : noisevarL; noisevarchrom[(i1 >> 1)*width2 + (j1 >> 1)] = useNoiseCCurve ? maxNoiseVarab * ccalc[i >> 1][j >> 1] : 1.f; } else { @@ -982,29 +953,29 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef } } else {//RGB mode #ifdef _RT_NESTED_OPENMP - #pragma omp parallel for num_threads(denoiseNestedLevels) if(denoiseNestedLevels>1) + #pragma omp parallel for num_threads(denoiseNestedLevels) if (denoiseNestedLevels>1) #endif - for (int i = tiletop; i < tilebottom; i++) { + for (int i = tiletop; i < tilebottom; ++i) { int i1 = i - tiletop; - for (int j = tileleft; j < tileright; j++) { + for (int j = tileleft; j < tileright; ++j) { int j1 = j - tileleft; float X = gain * src->r(i, j); float Y = gain * src->g(i, j); float Z = gain * src->b(i, j); //conversion colorspace to determine luminance with no gamma - X = X < 65535.0f ? gamcurve[X] : (Color::gamma((double)X / 65535.0, gam, gamthresh, gamslope, 1.0, 0.0) * 32768.0f); - Y = Y < 65535.0f ? gamcurve[Y] : (Color::gamma((double)Y / 65535.0, gam, gamthresh, gamslope, 1.0, 0.0) * 32768.0f); - Z = Z < 65535.0f ? gamcurve[Z] : (Color::gamma((double)Z / 65535.0, gam, gamthresh, gamslope, 1.0, 0.0) * 32768.0f); + X = X < 65535.0f ? gamcurve[X] : (Color::gamma(static_cast(X) / 65535.0, gam, gamthresh, gamslope, 1.0, 0.0) * 32768.0f); + Y = Y < 65535.0f ? gamcurve[Y] : (Color::gamma(static_cast(Y) / 65535.0, gam, gamthresh, gamslope, 1.0, 0.0) * 32768.0f); + Z = Z < 65535.0f ? gamcurve[Z] : (Color::gamma(static_cast(Z) / 65535.0, gam, gamthresh, gamslope, 1.0, 0.0) * 32768.0f); //end chroma labdn->L[i1][j1] = Y; labdn->a[i1][j1] = (X - Y); labdn->b[i1][j1] = (Y - Z); - if(((i1 | j1) & 1) == 0) { - if(numTries == 1) { + if (((i1 | j1) & 1) == 0) { + if (numTries == 1) { noisevarlum[(i1 >> 1)*width2 + (j1 >> 1)] = useNoiseLCurve ? lumcalc[i >> 1][j >> 1] : noisevarL; noisevarchrom[(i1 >> 1)*width2 + (j1 >> 1)] = useNoiseCCurve ? maxNoiseVarab * ccalc[i >> 1][j >> 1] : 1.f; } else { @@ -1017,13 +988,13 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef } } else {//image is not raw; use Lab parametrization #ifdef _RT_NESTED_OPENMP - #pragma omp parallel for num_threads(denoiseNestedLevels) if(denoiseNestedLevels>1) + #pragma omp parallel for num_threads(denoiseNestedLevels) if (denoiseNestedLevels>1) #endif - for (int i = tiletop; i < tilebottom; i++) { + for (int i = tiletop; i < tilebottom; ++i) { int i1 = i - tiletop; - for (int j = tileleft; j < tileright; j++) { + for (int j = tileleft; j < tileright; ++j) { int j1 = j - tileleft; float L, a, b; float rLum = src->r(i, j) ; //for denoise curves @@ -1038,9 +1009,9 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef float btmp = Color::igammatab_srgb[ src->b(i, j) ]; //modification Jacques feb 2013 // gamma slider different from raw - rtmp = rtmp < 65535.0f ? gamcurve[rtmp] : (Color::gamman((double)rtmp / 65535.0, gam) * 32768.0f); - gtmp = gtmp < 65535.0f ? gamcurve[gtmp] : (Color::gamman((double)gtmp / 65535.0, gam) * 32768.0f); - btmp = btmp < 65535.0f ? gamcurve[btmp] : (Color::gamman((double)btmp / 65535.0, gam) * 32768.0f); + rtmp = rtmp < 65535.0f ? gamcurve[rtmp] : (Color::gamman(static_cast(rtmp) / 65535.0, gam) * 32768.0f); + gtmp = gtmp < 65535.0f ? gamcurve[gtmp] : (Color::gamman(static_cast(gtmp) / 65535.0, gam) * 32768.0f); + btmp = btmp < 65535.0f ? gamcurve[btmp] : (Color::gamman(static_cast(btmp) / 65535.0, gam) * 32768.0f); float X, Y, Z; Color::rgbxyz(rtmp, gtmp, btmp, X, Y, Z, wp); @@ -1051,24 +1022,24 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef labdn->a[i1][j1] = a; labdn->b[i1][j1] = b; - if(((i1 | j1) & 1) == 0) { + if (((i1 | j1) & 1) == 0) { float Llum, alum, blum; - if(useNoiseLCurve || useNoiseCCurve) { + if (useNoiseLCurve || useNoiseCCurve) { float XL, YL, ZL; Color::rgbxyz(rLum, gLum, bLum, XL, YL, ZL, wp); Color::XYZ2Lab(XL, YL, ZL, Llum, alum, blum); } - if(useNoiseLCurve) { + if (useNoiseLCurve) { float kN = Llum; float epsi = 0.01f; - if(kN < 2.f) { + if (kN < 2.f) { kN = 2.f; } - if(kN > 32768.f) { + if (kN > 32768.f) { kN = 32768.f; } @@ -1080,12 +1051,12 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef noisevarlum[(i1 >> 1)*width2 + (j1 >> 1)] = noisevarL; } - if(useNoiseCCurve) { + if (useNoiseCCurve) { float aN = alum; float bN = blum; float cN = sqrtf(SQR(aN) + SQR(bN)); - if(cN < 100.f) { + if (cN < 100.f) { cN = 100.f; //avoid divided by zero ??? } @@ -1105,23 +1076,23 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef //binary 1 or 0 for each level, eg subsampling = 0 means no subsampling, 1 means subsample //the first level only, 7 means subsample the first three levels, etc. //actual implementation only works with subsampling set to 1 - float interm_medT = (float) dnparams.chroma / 10.0; + float interm_medT = static_cast( dnparams.chroma) / 10.0; bool execwavelet = true; - if(!denoiseLuminance && interm_medT < 0.05f && dnparams.median && (dnparams.methodmed == "Lab" || dnparams.methodmed == "Lonly")) { + if (!denoiseLuminance && interm_medT < 0.05f && dnparams.median && (dnparams.methodmed == "Lab" || dnparams.methodmed == "Lonly")) { execwavelet = false; //do not exec wavelet if sliders luminance and chroma are very small and median need } //we considered user don't want wavelet - if(settings->leveldnautsimpl == 1 && dnparams.Cmethod != "MAN") { + if (settings->leveldnautsimpl == 1 && dnparams.Cmethod != "MAN") { execwavelet = true; } - if(settings->leveldnautsimpl == 0 && dnparams.C2method != "MANU") { + if (settings->leveldnautsimpl == 0 && dnparams.C2method != "MANU") { execwavelet = true; } - if(execwavelet) {//gain time if user choose only median sliders L <=1 slider chrom master < 1 + if (execwavelet) {//gain time if user choose only median sliders L <=1 slider chrom master < 1 wavelet_decomposition* Ldecomp; wavelet_decomposition* adecomp; @@ -1129,66 +1100,66 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef float maxreal = max(realred, realblue); //increase the level of wavelet if user increase much or very much sliders - if( maxreal < 8.f) { + if (maxreal < 8.f) { levwav = 5; - } else if( maxreal < 10.f) { + } else if (maxreal < 10.f) { levwav = 6; - } else if( maxreal < 15.f) { + } else if (maxreal < 15.f) { levwav = 7; } else { levwav = 8; //maximum ==> I have increase Maxlevel in cplx_wavelet_dec.h from 8 to 9 } - if(nrQuality == QUALITY_HIGH) { + if (nrQuality == QUALITY_HIGH) { levwav += settings->nrwavlevel; //increase level for enhanced mode } - if(levwav > 8) { + if (levwav > 8) { levwav = 8; } int minsizetile = min(tilewidth, tileheight); int maxlev2 = 8; - if(minsizetile < 256) { + if (minsizetile < 256) { maxlev2 = 7; } - if(minsizetile < 128) { + if (minsizetile < 128) { maxlev2 = 6; } - if(minsizetile < 64) { + if (minsizetile < 64) { maxlev2 = 5; } levwav = min(maxlev2, levwav); - // if (settings->verbose) printf("levwavelet=%i noisevarA=%f noisevarB=%f \n",levwav, noisevarab_r, noisevarab_b ); + // if (settings->verbose) printf("levwavelet=%i noisevarA=%f noisevarB=%f \n",levwav, noisevarab_r, noisevarab_b); Ldecomp = new wavelet_decomposition (labdn->L[0], labdn->W, labdn->H, levwav, 1, 1, max(1, denoiseNestedLevels)); - if(Ldecomp->memoryAllocationFailed) { + if (Ldecomp->memoryAllocationFailed) { memoryAllocationFailed = true; } float madL[8][3]; - if(!memoryAllocationFailed) { + if (!memoryAllocationFailed) { // precalculate madL, because it's used in adecomp and bdecomp int maxlvl = Ldecomp->maxlevel(); #ifdef _RT_NESTED_OPENMP - #pragma omp parallel for schedule(dynamic) collapse(2) num_threads(denoiseNestedLevels) if(denoiseNestedLevels>1) + #pragma omp parallel for schedule(dynamic) collapse(2) num_threads(denoiseNestedLevels) if (denoiseNestedLevels>1) #endif - for (int lvl = 0; lvl < maxlvl; lvl++) { - for (int dir = 1; dir < 4; dir++) { + for (int lvl = 0; lvl < maxlvl; ++lvl) { + for (int dir = 1; dir < 4; ++dir) { // compute median absolute deviation (MAD) of detail coefficients as robust noise estimator int Wlvl_L = Ldecomp->level_W(lvl); int Hlvl_L = Ldecomp->level_H(lvl); float ** WavCoeffs_L = Ldecomp->level_coeffs(lvl); - if(!denoiseMethodRgb) { + if (!denoiseMethodRgb) { madL[lvl][dir - 1] = SQR(Mad(WavCoeffs_L[dir], Wlvl_L * Hlvl_L)); } else { madL[lvl][dir - 1] = SQR(MadRgb(WavCoeffs_L[dir], Wlvl_L * Hlvl_L)); @@ -1204,29 +1175,30 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef adecomp = new wavelet_decomposition (labdn->a[0], labdn->W, labdn->H, levwav, 1, 1, max(1, denoiseNestedLevels)); - if(adecomp->memoryAllocationFailed) { + if (adecomp->memoryAllocationFailed) { memoryAllocationFailed = true; } - if(!memoryAllocationFailed) { - if(nrQuality == QUALITY_STANDARD) { - if(!WaveletDenoiseAllAB(*Ldecomp, *adecomp, noisevarchrom, madL, noisevarab_r, useNoiseCCurve, autoch, denoiseMethodRgb )) { //enhance mode + if (!memoryAllocationFailed) { + if (nrQuality == QUALITY_STANDARD) { + if (!WaveletDenoiseAllAB(*Ldecomp, *adecomp, noisevarchrom, madL, noisevarab_r, useNoiseCCurve, autoch, denoiseMethodRgb)) { //enhance mode memoryAllocationFailed = true; } - } else { /*if(nrQuality==QUALITY_HIGH)*/ - if(!WaveletDenoiseAll_BiShrinkAB(*Ldecomp, *adecomp, noisevarchrom, madL, noisevarab_r, useNoiseCCurve, autoch, denoiseMethodRgb )) { //enhance mode + } else { /*if (nrQuality==QUALITY_HIGH)*/ + if (!WaveletDenoiseAll_BiShrinkAB(*Ldecomp, *adecomp, noisevarchrom, madL, noisevarab_r, useNoiseCCurve, autoch, denoiseMethodRgb)) { //enhance mode memoryAllocationFailed = true; } - if(!memoryAllocationFailed) - if(!WaveletDenoiseAllAB(*Ldecomp, *adecomp, noisevarchrom, madL, noisevarab_r, useNoiseCCurve, autoch, denoiseMethodRgb )) { + if (!memoryAllocationFailed) { + if (!WaveletDenoiseAllAB(*Ldecomp, *adecomp, noisevarchrom, madL, noisevarab_r, useNoiseCCurve, autoch, denoiseMethodRgb)) { memoryAllocationFailed = true; } + } } } - if(!memoryAllocationFailed) { - if(kall == 0) { + if (!memoryAllocationFailed) { + if (kall == 0) { Noise_residualAB(*adecomp, chresid, chmaxresid, denoiseMethodRgb); chresidtemp = chresid; chmaxresidtemp = chmaxresid; @@ -1237,32 +1209,33 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef delete adecomp; - if(!memoryAllocationFailed) { + if (!memoryAllocationFailed) { wavelet_decomposition* bdecomp = new wavelet_decomposition (labdn->b[0], labdn->W, labdn->H, levwav, 1, 1, max(1, denoiseNestedLevels)); - if(bdecomp->memoryAllocationFailed) { + if (bdecomp->memoryAllocationFailed) { memoryAllocationFailed = true; } - if(!memoryAllocationFailed) { - if(nrQuality == QUALITY_STANDARD) { - if(!WaveletDenoiseAllAB(*Ldecomp, *bdecomp, noisevarchrom, madL, noisevarab_b, useNoiseCCurve, autoch, denoiseMethodRgb )) { //enhance mode + if (!memoryAllocationFailed) { + if (nrQuality == QUALITY_STANDARD) { + if (!WaveletDenoiseAllAB(*Ldecomp, *bdecomp, noisevarchrom, madL, noisevarab_b, useNoiseCCurve, autoch, denoiseMethodRgb)) { //enhance mode memoryAllocationFailed = true; } - } else { /*if(nrQuality==QUALITY_HIGH)*/ - if(!WaveletDenoiseAll_BiShrinkAB(*Ldecomp, *bdecomp, noisevarchrom, madL, noisevarab_b, useNoiseCCurve, autoch, denoiseMethodRgb )) { //enhance mode + } else { /*if (nrQuality==QUALITY_HIGH)*/ + if (!WaveletDenoiseAll_BiShrinkAB(*Ldecomp, *bdecomp, noisevarchrom, madL, noisevarab_b, useNoiseCCurve, autoch, denoiseMethodRgb)) { //enhance mode memoryAllocationFailed = true; } - if(!memoryAllocationFailed) - if(!WaveletDenoiseAllAB(*Ldecomp, *bdecomp, noisevarchrom, madL, noisevarab_b, useNoiseCCurve, autoch, denoiseMethodRgb )) { + if (!memoryAllocationFailed) { + if (!WaveletDenoiseAllAB(*Ldecomp, *bdecomp, noisevarchrom, madL, noisevarab_b, useNoiseCCurve, autoch, denoiseMethodRgb)) { memoryAllocationFailed = true; } + } } } - if(!memoryAllocationFailed) { - if(kall == 0) { + if (!memoryAllocationFailed) { + if (kall == 0) { Noise_residualAB(*bdecomp, chresid, chmaxresid, denoiseMethodRgb); chresid += chresidtemp; chmaxresid += chmaxresidtemp; @@ -1276,36 +1249,38 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef delete bdecomp; - if(!memoryAllocationFailed) { - if(denoiseLuminance) { + if (!memoryAllocationFailed) { + if (denoiseLuminance) { int edge = 0; - if(nrQuality == QUALITY_STANDARD) { - if(!WaveletDenoiseAllL(*Ldecomp, noisevarlum, madL, NULL, edge)) { //enhance mode + if (nrQuality == QUALITY_STANDARD) { + if (!WaveletDenoiseAllL(*Ldecomp, noisevarlum, madL, nullptr, edge)) { //enhance mode memoryAllocationFailed = true; } - } else { /*if(nrQuality==QUALITY_HIGH)*/ - if(!WaveletDenoiseAll_BiShrinkL(*Ldecomp, noisevarlum, madL)) { //enhance mode + } else { /*if (nrQuality==QUALITY_HIGH)*/ + if (!WaveletDenoiseAll_BiShrinkL(*Ldecomp, noisevarlum, madL)) { //enhance mode memoryAllocationFailed = true; } - if(!memoryAllocationFailed) - if(!WaveletDenoiseAllL(*Ldecomp, noisevarlum, madL, NULL, edge)) { + if (!memoryAllocationFailed) { + if (!WaveletDenoiseAllL(*Ldecomp, noisevarlum, madL, nullptr, edge)) { memoryAllocationFailed = true; } + } } - if(!memoryAllocationFailed) { + if (!memoryAllocationFailed) { // copy labdn->L to Lin before it gets modified by reconstruction Lin = new array2D(width, height); #ifdef _RT_NESTED_OPENMP - #pragma omp parallel for num_threads(denoiseNestedLevels) if(denoiseNestedLevels>1) + #pragma omp parallel for num_threads(denoiseNestedLevels) if (denoiseNestedLevels>1) #endif - for(int i = 0; i < height; i++) - for(int j = 0; j < width; j++) { + for (int i = 0; i < height; ++i) { + for (int j = 0; j < width; ++j) { (*Lin)[i][j] = labdn->L[i][j]; } + } Ldecomp->reconstruct(labdn->L[0]); } @@ -1316,78 +1291,78 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef delete Ldecomp; } - if(!memoryAllocationFailed) { - if( (metchoice == 1 || metchoice == 2 || metchoice == 3 || metchoice == 4) && dnparams.median) { + if (!memoryAllocationFailed) { + if ((metchoice == 1 || metchoice == 2 || metchoice == 3 || metchoice == 4) && dnparams.median) { float** tmL; int wid = labdn->W; int hei = labdn->H; tmL = new float*[hei]; - for (int i = 0; i < hei; i++) { + for (int i = 0; i < hei; ++i) { tmL[i] = new float[wid]; } - mediantype medianTypeL = MED_3X3SOFT; - mediantype medianTypeAB = MED_3X3SOFT; + Median medianTypeL = Median::TYPE_3X3_SOFT; + Median medianTypeAB = Median::TYPE_3X3_SOFT; - if(dnparams.medmethod == "soft") { - if(metchoice != 4) { - medianTypeL = medianTypeAB = MED_3X3SOFT; + if (dnparams.medmethod == "soft") { + if (metchoice != 4) { + medianTypeL = medianTypeAB = Median::TYPE_3X3_SOFT; } else { - medianTypeL = MED_3X3SOFT; - medianTypeAB = MED_3X3SOFT; + medianTypeL = Median::TYPE_3X3_SOFT; + medianTypeAB = Median::TYPE_3X3_SOFT; } - } else if(dnparams.medmethod == "33") { - if(metchoice != 4) { - medianTypeL = medianTypeAB = MED_3X3STRONG; + } else if (dnparams.medmethod == "33") { + if (metchoice != 4) { + medianTypeL = medianTypeAB = Median::TYPE_3X3_STRONG; } else { - medianTypeL = MED_3X3SOFT; - medianTypeAB = MED_3X3STRONG; + medianTypeL = Median::TYPE_3X3_SOFT; + medianTypeAB = Median::TYPE_3X3_STRONG; } - } else if(dnparams.medmethod == "55soft") { - if(metchoice != 4) { - medianTypeL = medianTypeAB = MED_5X5SOFT; + } else if (dnparams.medmethod == "55soft") { + if (metchoice != 4) { + medianTypeL = medianTypeAB = Median::TYPE_5X5_SOFT; } else { - medianTypeL = MED_3X3SOFT; - medianTypeAB = MED_5X5SOFT; + medianTypeL = Median::TYPE_3X3_SOFT; + medianTypeAB = Median::TYPE_5X5_SOFT; } - } else if(dnparams.medmethod == "55") { - if(metchoice != 4) { - medianTypeL = medianTypeAB = MED_5X5STRONG; + } else if (dnparams.medmethod == "55") { + if (metchoice != 4) { + medianTypeL = medianTypeAB = Median::TYPE_5X5_STRONG; } else { - medianTypeL = MED_3X3STRONG; - medianTypeAB = MED_5X5STRONG; + medianTypeL = Median::TYPE_3X3_STRONG; + medianTypeAB = Median::TYPE_5X5_STRONG; } - } else if(dnparams.medmethod == "77") { - if(metchoice != 4) { - medianTypeL = medianTypeAB = MED_7X7; + } else if (dnparams.medmethod == "77") { + if (metchoice != 4) { + medianTypeL = medianTypeAB = Median::TYPE_7X7; } else { - medianTypeL = MED_3X3STRONG; - medianTypeAB = MED_7X7; + medianTypeL = Median::TYPE_3X3_STRONG; + medianTypeAB = Median::TYPE_7X7; } - } else if(dnparams.medmethod == "99") { - if(metchoice != 4) { - medianTypeL = medianTypeAB = MED_9X9; + } else if (dnparams.medmethod == "99") { + if (metchoice != 4) { + medianTypeL = medianTypeAB = Median::TYPE_9X9; } else { - medianTypeL = MED_5X5SOFT; - medianTypeAB = MED_9X9; + medianTypeL = Median::TYPE_5X5_SOFT; + medianTypeAB = Median::TYPE_9X9; } } if (metchoice == 1 || metchoice == 2 || metchoice == 4) { - Median_Denoise( labdn->L, labdn->L, wid, hei, medianTypeL, dnparams.passes, denoiseNestedLevels, tmL); + Median_Denoise(labdn->L, labdn->L, wid, hei, medianTypeL, dnparams.passes, denoiseNestedLevels, tmL); } - if(metchoice == 2 || metchoice == 3 || metchoice == 4) { - Median_Denoise( labdn->a, labdn->a, wid, hei, medianTypeAB, dnparams.passes, denoiseNestedLevels, tmL); - Median_Denoise( labdn->b, labdn->b, wid, hei, medianTypeAB, dnparams.passes, denoiseNestedLevels, tmL); + if (metchoice == 2 || metchoice == 3 || metchoice == 4) { + Median_Denoise(labdn->a, labdn->a, wid, hei, medianTypeAB, dnparams.passes, denoiseNestedLevels, tmL); + Median_Denoise(labdn->b, labdn->b, wid, hei, medianTypeAB, dnparams.passes, denoiseNestedLevels, tmL); } - for (int i = 0; i < hei; i++) { - delete [] tmL[i]; + for (int i = 0; i < hei; ++i) { + delete[] tmL[i]; } - delete [] tmL; + delete[] tmL; } //wavelet denoised L channel @@ -1398,8 +1373,8 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef // blocks are not the same thing as tiles! // calculation for detail recovery blocks - const int numblox_W = ceil(((float)(width)) / (offset)) + 2 * blkrad; - const int numblox_H = ceil(((float)(height)) / (offset)) + 2 * blkrad; + const int numblox_W = ceil((static_cast(width)) / (offset)) + 2 * blkrad; + const int numblox_H = ceil((static_cast(height)) / (offset)) + 2 * blkrad; @@ -1410,23 +1385,24 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef // Main detail recovery algorithm: Block loop //DCT block data storage - if(denoiseLuminance /*&& execwavelet*/) { + if (denoiseLuminance /*&& execwavelet*/) { //residual between input and denoised L channel array2D Ldetail(width, height, ARRAY2D_CLEAR_DATA); //pixel weight array2D totwt(width, height, ARRAY2D_CLEAR_DATA); //weight for combining DCT blocks - if(numtiles == 1) - for(int i = 0; i < denoiseNestedLevels * numthreads; i++) { - LbloxArray[i] = (float*) fftwf_malloc(max_numblox_W * TS * TS * sizeof(float)); - fLbloxArray[i] = (float*) fftwf_malloc(max_numblox_W * TS * TS * sizeof(float)); + if (numtiles == 1) { + for (int i = 0; i < denoiseNestedLevels * numthreads; ++i) { + LbloxArray[i] = reinterpret_cast( fftwf_malloc(max_numblox_W * TS * TS * sizeof(float))); + fLbloxArray[i] = reinterpret_cast( fftwf_malloc(max_numblox_W * TS * TS * sizeof(float))); } + } #ifdef _RT_NESTED_OPENMP int masterThread = omp_get_thread_num(); #endif #ifdef _RT_NESTED_OPENMP - #pragma omp parallel num_threads(denoiseNestedLevels) if(denoiseNestedLevels>1) + #pragma omp parallel num_threads(denoiseNestedLevels) if (denoiseNestedLevels>1) #endif { #ifdef _RT_NESTED_OPENMP @@ -1443,12 +1419,12 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef #pragma omp for #endif - for (int vblk = 0; vblk < numblox_H; vblk++) { + for (int vblk = 0; vblk < numblox_H; ++vblk) { int top = (vblk - blkrad) * offset; float * datarow = pBuf + blkrad * offset; - for (int i = 0; i < TS; i++) { + for (int i = 0; i < TS; ++i) { int row = top + i; int rr = row; @@ -1458,40 +1434,40 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef rr = MAX(0, 2 * height - 2 - row); } - for (int j = 0; j < labdn->W; j++) { + for (int j = 0; j < labdn->W; ++j) { datarow[j] = ((*Lin)[rr][j] - labdn->L[rr][j]); } - for (int j = -blkrad * offset; j < 0; j++) { + for (int j = -blkrad * offset; j < 0; ++j) { datarow[j] = datarow[MIN(-j, width - 1)]; } - for (int j = width; j < width + TS + blkrad * offset; j++) { + for (int j = width; j < width + TS + blkrad * offset; ++j) { datarow[j] = datarow[MAX(0, 2 * width - 2 - j)]; }//now we have a padded data row //now fill this row of the blocks with Lab high pass data - for (int hblk = 0; hblk < numblox_W; hblk++) { + for (int hblk = 0; hblk < numblox_W; ++hblk) { int left = (hblk - blkrad) * offset; int indx = (hblk) * TS; //index of block in malloc - if(top + i >= 0 && top + i < height) { + if (top + i >= 0 && top + i < height) { int j; - for (j = 0; j < min((-left), TS); j++) { + for (j = 0; j < min((-left), TS); ++j) { Lblox[(indx + i)*TS + j] = tilemask_in[i][j] * datarow[left + j]; // luma data } - for (; j < min(TS, width - left); j++) { + for (; j < min(TS, width - left); ++j) { Lblox[(indx + i)*TS + j] = tilemask_in[i][j] * datarow[left + j]; // luma data totwt[top + i][left + j] += tilemask_in[i][j] * tilemask_out[i][j]; } - for (; j < TS; j++) { + for (; j < TS; ++j) { Lblox[(indx + i)*TS + j] = tilemask_in[i][j] * datarow[left + j]; // luma data } } else { - for (int j = 0; j < TS; j++) { + for (int j = 0; j < TS; ++j) { Lblox[(indx + i)*TS + j] = tilemask_in[i][j] * datarow[left + j]; // luma data } } @@ -1502,7 +1478,7 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //fftwf_print_plan (plan_forward_blox); - if(numblox_W == max_numblox_W) { + if (numblox_W == max_numblox_W) { fftwf_execute_r2r(plan_forward_blox[0], Lblox, fLblox); // DCT an entire row of tiles } else { fftwf_execute_r2r(plan_forward_blox[1], Lblox, fLblox); // DCT an entire row of tiles @@ -1512,14 +1488,14 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef // now process the vblk row of blocks for noise reduction - for (int hblk = 0; hblk < numblox_W; hblk++) { - RGBtile_denoise (fLblox, hblk, noisevar_Ldetail, nbrwt, blurbuffer ); + for (int hblk = 0; hblk < numblox_W; ++hblk) { + RGBtile_denoise (fLblox, hblk, noisevar_Ldetail, nbrwt, blurbuffer); }//end of horizontal block loop //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //now perform inverse FT of an entire row of blocks - if(numblox_W == max_numblox_W) { + if (numblox_W == max_numblox_W) { fftwf_execute_r2r(plan_backward_blox[0], fLblox, Lblox); //for DCT } else { fftwf_execute_r2r(plan_backward_blox[1], fLblox, Lblox); //for DCT @@ -1528,7 +1504,7 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef int topproc = (vblk - blkrad) * offset; //add row of blocks to output image tile - RGBoutput_tile_row (Lblox, Ldetail, tilemask_out, height, width, topproc ); + RGBoutput_tile_row (Lblox, Ldetail, tilemask_out, height, width, topproc); //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -1540,11 +1516,11 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #ifdef _RT_NESTED_OPENMP - #pragma omp parallel for num_threads(denoiseNestedLevels) if(denoiseNestedLevels>1) + #pragma omp parallel for num_threads(denoiseNestedLevels) if (denoiseNestedLevels>1) #endif - for (int i = 0; i < height; i++) { - for (int j = 0; j < width; j++) { + for (int i = 0; i < height; ++i) { + for (int j = 0; j < width; ++j) { //may want to include masking threshold for large hipass data to preserve edges/detail labdn->L[i][j] += Ldetail[i][j] / totwt[i][j]; //note that labdn initially stores the denoised hipass data } @@ -1559,22 +1535,22 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef float Hmask[width + 1] ALIGNED16; float newGain; - if(numtiles > 1) { - for (int i = 0; i < height; i++) { + if (numtiles > 1) { + for (int i = 0; i < height; ++i) { Vmask[i] = 1; } newGain = 1.f; - if(isRAW) { + if (isRAW) { newGain = gain; } - for (int j = 0; j < width; j++) { + for (int j = 0; j < width; ++j) { Hmask[j] = 1.f / newGain; } - for (int i = 0; i < overlap; i++) { + for (int i = 0; i < overlap; ++i) { float mask = SQR(xsinf((M_PI * i) / (2 * overlap))); if (tiletop > 0) { @@ -1599,7 +1575,7 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef //convert back to RGB and write to destination array if (isRAW) { - if(!denoiseMethodRgb) {//Lab mode + if (!denoiseMethodRgb) {//Lab mode realred /= 100.f; realblue /= 100.f; @@ -1607,10 +1583,10 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef #pragma omp parallel for schedule(dynamic,16) num_threads(denoiseNestedLevels) #endif - for (int i = tiletop; i < tilebottom; i++) { + for (int i = tiletop; i < tilebottom; ++i) { int i1 = i - tiletop; - for (int j = tileleft; j < tileright; j++) { + for (int j = tileleft; j < tileright; ++j) { int j1 = j - tileleft; //modification Jacques feb 2013 //true conversion Lab==>xyz @@ -1619,7 +1595,7 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef float b = labdn->b[i1][j1]; float c_h = SQR(a) + SQR(b); - if(c_h > 9000000.f) { + if (c_h > 9000000.f) { a *= 1.f + qhighFactor * realred; b *= 1.f + qhighFactor * realblue; } @@ -1640,7 +1616,7 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef g_ = (*denoisegamtab)[g_]; b_ = (*denoisegamtab)[b_]; - if(numtiles == 1) { + if (numtiles == 1) { dsttmp->r(i, j) = newGain * r_; dsttmp->g(i, j) = newGain * g_; dsttmp->b(i, j) = newGain * b_; @@ -1657,14 +1633,14 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef #pragma omp parallel for num_threads(denoiseNestedLevels) #endif - for (int i = tiletop; i < tilebottom; i++) { + for (int i = tiletop; i < tilebottom; ++i) { int i1 = i - tiletop; - for (int j = tileleft; j < tileright; j++) { + for (int j = tileleft; j < tileright; ++j) { int j1 = j - tileleft; float c_h = sqrt(SQR(labdn->a[i1][j1]) + SQR(labdn->b[i1][j1])); - if(c_h > 3000.f) { + if (c_h > 3000.f) { labdn->a[i1][j1] *= 1.f + qhighFactor * realred / 100.f; labdn->b[i1][j1] *= 1.f + qhighFactor * realblue / 100.f; } @@ -1674,11 +1650,11 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef float Z = Y - (labdn->b[i1][j1]); - X = X < 32768.0f ? igamcurve[X] : (Color::gamma((float)X / 32768.0f, igam, igamthresh, igamslope, 1.0, 0.0) * 65535.0f); - Y = Y < 32768.0f ? igamcurve[Y] : (Color::gamma((float)Y / 32768.0f, igam, igamthresh, igamslope, 1.0, 0.0) * 65535.0f); - Z = Z < 32768.0f ? igamcurve[Z] : (Color::gamma((float)Z / 32768.0f, igam, igamthresh, igamslope, 1.0, 0.0) * 65535.0f); + X = X < 32768.0f ? igamcurve[X] : (Color::gamma(X / 32768.0f, igam, igamthresh, igamslope, 1.0, 0.0) * 65535.0f); + Y = Y < 32768.0f ? igamcurve[Y] : (Color::gamma(Y / 32768.0f, igam, igamthresh, igamslope, 1.0, 0.0) * 65535.0f); + Z = Z < 32768.0f ? igamcurve[Z] : (Color::gamma(Z / 32768.0f, igam, igamthresh, igamslope, 1.0, 0.0) * 65535.0f); - if(numtiles == 1) { + if (numtiles == 1) { dsttmp->r(i, j) = newGain * X; dsttmp->g(i, j) = newGain * Y; dsttmp->b(i, j) = newGain * Z; @@ -1697,10 +1673,10 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef #pragma omp parallel for num_threads(denoiseNestedLevels) #endif - for (int i = tiletop; i < tilebottom; i++) { + for (int i = tiletop; i < tilebottom; ++i) { int i1 = i - tiletop; - for (int j = tileleft; j < tileright; j++) { + for (int j = tileleft; j < tileright; ++j) { int j1 = j - tileleft; //modification Jacques feb 2013 float L = labdn->L[i1][j1]; @@ -1708,7 +1684,7 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef float b = labdn->b[i1][j1]; float c_h = sqrt(SQR(a) + SQR(b)); - if(c_h > 3000.f) { + if (c_h > 3000.f) { a *= 1.f + qhighFactor * realred / 100.f; b *= 1.f + qhighFactor * realblue / 100.f; } @@ -1719,11 +1695,11 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef float r_, g_, b_; Color::xyz2rgb(X, Y, Z, r_, g_, b_, wip); //gamma slider is different from Raw - r_ = r_ < 32768.0f ? igamcurve[r_] : (Color::gamman((float)r_ / 32768.0f, igam) * 65535.0f); - g_ = g_ < 32768.0f ? igamcurve[g_] : (Color::gamman((float)g_ / 32768.0f, igam) * 65535.0f); - b_ = b_ < 32768.0f ? igamcurve[b_] : (Color::gamman((float)b_ / 32768.0f, igam) * 65535.0f); + r_ = r_ < 32768.0f ? igamcurve[r_] : (Color::gamman(r_ / 32768.0f, igam) * 65535.0f); + g_ = g_ < 32768.0f ? igamcurve[g_] : (Color::gamman(g_ / 32768.0f, igam) * 65535.0f); + b_ = b_ < 32768.0f ? igamcurve[b_] : (Color::gamman(b_ / 32768.0f, igam) * 65535.0f); - if(numtiles == 1) { + if (numtiles == 1) { dsttmp->r(i, j) = newGain * r_; dsttmp->g(i, j) = newGain * g_; dsttmp->b(i, j) = newGain * b_; @@ -1742,22 +1718,22 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef delete labdn; - if(denoiseLuminance) { + if (denoiseLuminance) { delete Lin; } }//end of tile row }//end of tile loop - if(numtiles > 1 || !isRAW || (!useNoiseCCurve && !useNoiseLCurve)) { - delete [] noisevarlum; - delete [] noisevarchrom; + if (numtiles > 1 || !isRAW || (!useNoiseCCurve && !useNoiseLCurve)) { + delete[] noisevarlum; + delete[] noisevarchrom; } } - if(denoiseLuminance) { - for(int i = 0; i < denoiseNestedLevels * numthreads; i++) { + if (denoiseLuminance) { + for (int i = 0; i < denoiseNestedLevels * numthreads; ++i) { fftwf_free(LbloxArray[i]); fftwf_free(fLbloxArray[i]); } @@ -1768,10 +1744,10 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef #endif //copy denoised image to output - if(numtiles > 1) { - if(!memoryAllocationFailed) { + if (numtiles > 1) { + if (!memoryAllocationFailed) { dsttmp->copyData(dst); - } else if(dst != src) { + } else if (dst != src) { src->copyData(dst); } @@ -1783,25 +1759,26 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef #pragma omp parallel for #endif - for(int i = 0; i < dst->height; i++) - for(int j = 0; j < dst->width; j++) { + for (int i = 0; i < dst->height; ++i) { + for (int j = 0; j < dst->width; ++j) { dst->r(i, j) = Color::gammatab_srgb[ dst->r(i, j) ]; dst->g(i, j) = Color::gammatab_srgb[ dst->g(i, j) ]; dst->b(i, j) = Color::gammatab_srgb[ dst->b(i, j) ]; } + } } - if(denoiseLuminance) { + if (denoiseLuminance) { // destroy the plans - fftwf_destroy_plan( plan_forward_blox[0] ); - fftwf_destroy_plan( plan_backward_blox[0] ); - fftwf_destroy_plan( plan_forward_blox[1] ); - fftwf_destroy_plan( plan_backward_blox[1] ); + fftwf_destroy_plan(plan_forward_blox[0]); + fftwf_destroy_plan(plan_backward_blox[0]); + fftwf_destroy_plan(plan_forward_blox[1]); + fftwf_destroy_plan(plan_backward_blox[1]); fftwf_cleanup(); } } while(memoryAllocationFailed && numTries < 2 && (options.rgbDenoiseThreadLimit == 0) && !ponder); - if(memoryAllocationFailed) { + if (memoryAllocationFailed) { printf("tiled denoise failed due to isufficient memory. Output is not denoised!\n"); } @@ -1809,13 +1786,13 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef //median 3x3 in complement on RGB - if(dnparams.methodmed == "RGB" && dnparams.median) { + if (dnparams.methodmed == "RGB" && dnparams.median) { //printf("RGB den\n"); int wid = dst->width, hei = dst->height; float** tm; tm = new float*[hei]; - for (int i = 0; i < hei; i++) { + for (int i = 0; i < hei; ++i) { tm[i] = new float[wid]; } @@ -1830,135 +1807,125 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef int methmed = 0; int border = 1; - if(dnparams.rgbmethod == "soft") { + if (dnparams.rgbmethod == "soft") { methmed = 0; - } else if(dnparams.rgbmethod == "33") { + } else if (dnparams.rgbmethod == "33") { methmed = 1; - } else if(dnparams.rgbmethod == "55") { + } else if (dnparams.rgbmethod == "55") { methmed = 3; border = 2; - } else if(dnparams.rgbmethod == "55soft") { + } else if (dnparams.rgbmethod == "55soft") { methmed = 2; border = 2; } - for(int iteration = 1; iteration <= dnparams.passes; iteration++) { + for (int iteration = 1; iteration <= dnparams.passes; ++iteration) { #pragma omp parallel { - if(methmed < 2) + if (methmed < 2) { #pragma omp for - for (int i = 1; i < hei - 1; i++) { - float pp[9], temp; - - if(methmed == 0) - for (int j = 1; j < wid - 1; j++) { - med2(source->r(i, j), source->r(i - 1, j), source->r(i + 1, j), source->r(i, j + 1), source->r(i, j - 1), tm[i][j]); //3x3 soft + for (int i = 1; i < hei - 1; ++i) { + if (methmed == 0) { + for (int j = 1; j < wid - 1; ++j) { + tm[i][j] = median(source->r(i, j), source->r(i - 1, j), source->r(i + 1, j), source->r(i, j + 1), source->r(i, j - 1)); //3x3 soft } - else - for (int j = 1; j < wid - 1; j++) { - med3(source->r(i, j), source->r(i - 1, j), source->r(i + 1, j), source->r(i, j + 1), source->r(i, j - 1), source->r(i - 1, j - 1), source->r(i - 1, j + 1), source->r(i + 1, j - 1), source->r(i + 1, j + 1), tm[i][j]); //3x3 + } else { + for (int j = 1; j < wid - 1; ++j) { + tm[i][j] = median(source->r(i, j), source->r(i - 1, j), source->r(i + 1, j), source->r(i, j + 1), source->r(i, j - 1), source->r(i - 1, j - 1), source->r(i - 1, j + 1), source->r(i + 1, j - 1), source->r(i + 1, j + 1)); //3x3 } + } } } else { #pragma omp for - for (int i = 2; i < hei - 2; i++) + for (int i = 2; i < hei - 2; ++i) { - float pp[25]; - - if(methmed == 3) { - float temp; - - for (int j = 2; j < wid - 2; j++) { - med5(source->r(i, j), source->r(i - 1, j), source->r(i + 1, j), source->r(i, j + 1), source->r(i, j - 1), source->r(i - 1, j - 1), source->r(i - 1, j + 1), source->r(i + 1, j - 1), source->r(i + 1, j + 1), + if (methmed == 3) { + for (int j = 2; j < wid - 2; ++j) { + tm[i][j] = median(source->r(i, j), source->r(i - 1, j), source->r(i + 1, j), source->r(i, j + 1), source->r(i, j - 1), source->r(i - 1, j - 1), source->r(i - 1, j + 1), source->r(i + 1, j - 1), source->r(i + 1, j + 1), source->r(i - 2, j), source->r(i + 2, j), source->r(i, j + 2), source->r(i, j - 2), source->r(i - 2, j - 2), source->r(i - 2, j + 2), source->r(i + 2, j - 2), source->r(i + 2, j + 2), - source->r(i - 2, j + 1), source->r(i + 2, j + 1), source->r(i - 1, j + 2), source->r(i - 1, j - 2), source->r(i - 2, j - 1), source->r(i + 2, j - 1), source->r(i + 1, j + 2), source->r(i + 1, j - 2), - tm[i][j]);//5x5 + source->r(i - 2, j + 1), source->r(i + 2, j + 1), source->r(i - 1, j + 2), source->r(i - 1, j - 2), source->r(i - 2, j - 1), source->r(i + 2, j - 1), source->r(i + 1, j + 2), source->r(i + 1, j - 2));//5x5 } - } else - for (int j = 2; j < wid - 2; j++) { - pp[0] = source->r(i, j); - pp[1] = source->r(i - 1, j); - pp[2] = source->r(i + 1, j); - pp[3] = source->r(i, j + 1); - pp[4] = source->r(i, j - 1); - pp[5] = source->r(i - 1, j - 1); - pp[6] = source->r(i - 1, j + 1); - pp[7] = source->r(i + 1, j - 1); - pp[8] = source->r(i + 1, j + 1); - pp[9] = source->r(i + 2, j); - pp[10] = source->r(i - 2, j); - pp[11] = source->r(i, j + 2); - pp[12] = source->r(i, j - 2); - fq_sort2(pp, 13); - tm[i][j] = pp[6]; //5x5 soft + } else { + for (int j = 2; j < wid - 2; ++j) { + tm[i][j] = median( + source->r(i, j), + source->r(i - 1, j), + source->r(i + 1, j), + source->r(i, j + 1), + source->r(i, j - 1), + source->r(i - 1, j - 1), + source->r(i - 1, j + 1), + source->r(i + 1, j - 1), + source->r(i + 1, j + 1), + source->r(i + 2, j), + source->r(i - 2, j), + source->r(i, j + 2), + source->r(i, j - 2) + ); // 5x5 soft } + } } } #ifdef _OPENMP #pragma omp for nowait #endif - for(int i = border; i < hei - border; i++ ) + for (int i = border; i < hei - border; ++i) { - for(int j = border; j < wid - border; j++) { + for (int j = border; j < wid - border; ++j) { dst->r(i, j) = tm[i][j]; } } - if(methmed < 2) + if (methmed < 2) { #pragma omp for - for (int i = 1; i < hei - 1; i++) { - float pp[9], temp; - - if(methmed == 0) - for (int j = 1; j < wid - 1; j++) { - med2(source->b(i, j), source->b(i - 1, j), source->b(i + 1, j), source->b(i, j + 1), source->b(i, j - 1), tm[i][j]); + for (int i = 1; i < hei - 1; ++i) { + if (methmed == 0) { + for (int j = 1; j < wid - 1; ++j) { + tm[i][j] = median(source->b(i, j), source->b(i - 1, j), source->b(i + 1, j), source->b(i, j + 1), source->b(i, j - 1)); } - else - for (int j = 1; j < wid - 1; j++) { - med3(source->b(i, j), source->b(i - 1, j), source->b(i + 1, j), source->b(i, j + 1), source->b(i, j - 1), source->b(i - 1, j - 1), source->b(i - 1, j + 1), source->b(i + 1, j - 1), source->b(i + 1, j + 1), tm[i][j]); + } else { + for (int j = 1; j < wid - 1; ++j) { + tm[i][j] = median(source->b(i, j), source->b(i - 1, j), source->b(i + 1, j), source->b(i, j + 1), source->b(i, j - 1), source->b(i - 1, j - 1), source->b(i - 1, j + 1), source->b(i + 1, j - 1), source->b(i + 1, j + 1)); } + } } } else { #pragma omp for - for (int i = 2; i < hei - 2; i++) + for (int i = 2; i < hei - 2; ++i) { - float pp[25]; - - if(methmed == 3) { - float temp; - - for (int j = 2; j < wid - 2; j++) { - med5(source->b(i, j), source->b(i - 1, j), source->b(i + 1, j), source->b(i, j + 1), source->b(i, j - 1), source->b(i - 1, j - 1), source->b(i - 1, j + 1), source->b(i + 1, j - 1), source->b(i + 1, j + 1), + if (methmed == 3) { + for (int j = 2; j < wid - 2; ++j) { + tm[i][j] = median(source->b(i, j), source->b(i - 1, j), source->b(i + 1, j), source->b(i, j + 1), source->b(i, j - 1), source->b(i - 1, j - 1), source->b(i - 1, j + 1), source->b(i + 1, j - 1), source->b(i + 1, j + 1), source->b(i - 2, j), source->b(i + 2, j), source->b(i, j + 2), source->b(i, j - 2), source->b(i - 2, j - 2), source->b(i - 2, j + 2), source->b(i + 2, j - 2), source->b(i + 2, j + 2), - source->b(i - 2, j + 1), source->b(i + 2, j + 1), source->b(i - 1, j + 2), source->b(i - 1, j - 2), source->b(i - 2, j - 1), source->b(i + 2, j - 1), source->b(i + 1, j + 2), source->b(i + 1, j - 2), - tm[i][j]);//5x5 + source->b(i - 2, j + 1), source->b(i + 2, j + 1), source->b(i - 1, j + 2), source->b(i - 1, j - 2), source->b(i - 2, j - 1), source->b(i + 2, j - 1), source->b(i + 1, j + 2), source->b(i + 1, j - 2)); // 5x5 } - } else - for (int j = 2; j < wid - 2; j++) { - pp[0] = source->b(i, j); - pp[1] = source->b(i - 1, j); - pp[2] = source->b(i + 1, j); - pp[3] = source->b(i, j + 1); - pp[4] = source->b(i, j - 1); - pp[5] = source->b(i - 1, j - 1); - pp[6] = source->b(i - 1, j + 1); - pp[7] = source->b(i + 1, j - 1); - pp[8] = source->b(i + 1, j + 1); - pp[9] = source->b(i + 2, j); - pp[10] = source->b(i - 2, j); - pp[11] = source->b(i, j + 2); - pp[12] = source->b(i, j - 2); - fq_sort2(pp, 13); - tm[i][j] = pp[6]; //5x5 soft + } else { + for (int j = 2; j < wid - 2; ++j) { + tm[i][j] = median( + source->b(i, j), + source->b(i - 1, j), + source->b(i + 1, j), + source->b(i, j + 1), + source->b(i, j - 1), + source->b(i - 1, j - 1), + source->b(i - 1, j + 1), + source->b(i + 1, j - 1), + source->b(i + 1, j + 1), + source->b(i + 2, j), + source->b(i - 2, j), + source->b(i, j + 2), + source->b(i, j - 2) + ); // 5x5 soft } + } } } @@ -1966,64 +1933,59 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef #pragma omp for nowait #endif - for(int i = border; i < hei - border; i++ ) + for (int i = border; i < hei - border; ++i) { - for(int j = border; j < wid - border; j++) { + for (int j = border; j < wid - border; ++j) { dst->b(i, j) = tm[i][j]; } } - if(methmed < 2) + if (methmed < 2) { #pragma omp for - for (int i = 1; i < hei - 1; i++) { - float pp[9], temp; - - if(methmed == 0) - for (int j = 1; j < wid - 1; j++) { - med2(source->g(i, j), source->g(i - 1, j), source->g(i + 1, j), source->g(i, j + 1), source->g(i, j - 1), tm[i][j]); + for (int i = 1; i < hei - 1; ++i) { + if (methmed == 0) { + for (int j = 1; j < wid - 1; ++j) { + tm[i][j] = median(source->g(i, j), source->g(i - 1, j), source->g(i + 1, j), source->g(i, j + 1), source->g(i, j - 1)); } - else - for (int j = 1; j < wid - 1; j++) { - med3(source->g(i, j), source->g(i - 1, j), source->g(i + 1, j), source->g(i, j + 1), source->g(i, j - 1), source->g(i - 1, j - 1), source->g(i - 1, j + 1), source->g(i + 1, j - 1), source->g(i + 1, j + 1), tm[i][j]); + } else { + for (int j = 1; j < wid - 1; ++j) { + tm[i][j] = median(source->g(i, j), source->g(i - 1, j), source->g(i + 1, j), source->g(i, j + 1), source->g(i, j - 1), source->g(i - 1, j - 1), source->g(i - 1, j + 1), source->g(i + 1, j - 1), source->g(i + 1, j + 1)); } + } } } else { #pragma omp for - for (int i = 2; i < hei - 2; i++) + for (int i = 2; i < hei - 2; ++i) { - float pp[25]; - - if(methmed == 3) { - float temp; - - for (int j = 2; j < wid - 2; j++) { - med5(source->g(i, j), source->g(i - 1, j), source->g(i + 1, j), source->g(i, j + 1), source->g(i, j - 1), source->g(i - 1, j - 1), source->g(i - 1, j + 1), source->g(i + 1, j - 1), source->g(i + 1, j + 1), + if (methmed == 3) { + for (int j = 2; j < wid - 2; ++j) { + tm[i][j] = median(source->g(i, j), source->g(i - 1, j), source->g(i + 1, j), source->g(i, j + 1), source->g(i, j - 1), source->g(i - 1, j - 1), source->g(i - 1, j + 1), source->g(i + 1, j - 1), source->g(i + 1, j + 1), source->g(i - 2, j), source->g(i + 2, j), source->g(i, j + 2), source->g(i, j - 2), source->g(i - 2, j - 2), source->g(i - 2, j + 2), source->g(i + 2, j - 2), source->g(i + 2, j + 2), - source->g(i - 2, j + 1), source->g(i + 2, j + 1), source->g(i - 1, j + 2), source->g(i - 1, j - 2), source->g(i - 2, j - 1), source->g(i + 2, j - 1), source->g(i + 1, j + 2), source->g(i + 1, j - 2), - tm[i][j]);//5x5 + source->g(i - 2, j + 1), source->g(i + 2, j + 1), source->g(i - 1, j + 2), source->g(i - 1, j - 2), source->g(i - 2, j - 1), source->g(i + 2, j - 1), source->g(i + 1, j + 2), source->g(i + 1, j - 2)); // 5x5 } - } else - for (int j = 2; j < wid - 2; j++) { - pp[0] = source->g(i, j); - pp[1] = source->g(i - 1, j); - pp[2] = source->g(i + 1, j); - pp[3] = source->g(i, j + 1); - pp[4] = source->g(i, j - 1); - pp[5] = source->g(i - 1, j - 1); - pp[6] = source->g(i - 1, j + 1); - pp[7] = source->g(i + 1, j - 1); - pp[8] = source->g(i + 1, j + 1); - pp[9] = source->g(i + 2, j); - pp[10] = source->g(i - 2, j); - pp[11] = source->g(i, j + 2); - pp[12] = source->g(i, j - 2); - fq_sort2(pp, 13); - tm[i][j] = pp[6]; //5x5 soft + } else { + for (int j = 2; j < wid - 2; ++j) { + tm[i][j] = median( + source->g(i, j), + source->g(i - 1, j), + source->g(i + 1, j), + source->g(i, j + 1), + source->g(i, j - 1), + source->g(i - 1, j - 1), + source->g(i - 1, j + 1), + source->g(i + 1, j - 1), + source->g(i + 1, j + 1), + source->g(i + 2, j), + source->g(i - 2, j), + source->g(i, j + 2), + source->g(i, j - 2) + ); // 5x5 soft } + } } } @@ -2031,29 +1993,29 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef #pragma omp for #endif - for(int i = border; i < hei - border; i++ ) + for (int i = border; i < hei - border; ++i) { - for(int j = border; j < wid - border; j++) { + for (int j = border; j < wid - border; ++j) { dst->g(i, j) = tm[i][j]; } } } } - for (int i = 0; i < hei; i++) { - delete [] tm[i]; + for (int i = 0; i < hei; ++i) { + delete[] tm[i]; } - delete [] tm; + delete[] tm; } //end median - if(noiseLCurve || useNoiseCCurve) { - delete [] lumcalcBuffer; - delete [] lumcalc; - delete [] ccalcBuffer; - delete [] ccalc; + if (noiseLCurve || useNoiseCCurve) { + delete[] lumcalcBuffer; + delete[] lumcalc; + delete[] ccalcBuffer; + delete[] ccalc; } //#ifdef _DEBUG @@ -2072,7 +2034,7 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -SSEFUNCTION void ImProcFunctions::RGBtile_denoise (float * fLblox, int hblproc, float noisevar_Ldetail, float * nbrwt, float * blurbuffer ) //for DCT +SSEFUNCTION void ImProcFunctions::RGBtile_denoise (float * fLblox, int hblproc, float noisevar_Ldetail, float * nbrwt, float * blurbuffer) //for DCT { int blkstart = hblproc * TS * TS; @@ -2080,17 +2042,17 @@ SSEFUNCTION void ImProcFunctions::RGBtile_denoise (float * fLblox, int hblproc, #ifdef __SSE2__ __m128 tempv; - __m128 noisevar_Ldetailv = _mm_set1_ps( noisevar_Ldetail ); - __m128 onev = _mm_set1_ps( 1.0f ); + __m128 noisevar_Ldetailv = _mm_set1_ps(noisevar_Ldetail); + __m128 onev = _mm_set1_ps(1.0f); for (int n = 0; n < TS * TS; n += 4) { //for DCT - tempv = onev - xexpf( -SQRV( LVF(nbrwt[n])) / noisevar_Ldetailv); - _mm_storeu_ps( &fLblox[blkstart + n], LVFU(fLblox[blkstart + n]) * tempv ); + tempv = onev - xexpf(-SQRV(LVF(nbrwt[n])) / noisevar_Ldetailv); + _mm_storeu_ps(&fLblox[blkstart + n], LVFU(fLblox[blkstart + n]) * tempv); }//output neighbor averaged result #else - for (int n = 0; n < TS * TS; n++) { //for DCT + for (int n = 0; n < TS * TS; ++n) { //for DCT fLblox[blkstart + n] *= (1 - xexpf(-SQR(nbrwt[n]) / noisevar_Ldetail)); }//output neighbor averaged result @@ -2105,29 +2067,30 @@ SSEFUNCTION void ImProcFunctions::RGBtile_denoise (float * fLblox, int hblproc, //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -void ImProcFunctions::RGBoutput_tile_row (float *bloxrow_L, float ** Ldetail, float ** tilemask_out, int height, int width, int top ) +void ImProcFunctions::RGBoutput_tile_row (float *bloxrow_L, float ** Ldetail, float ** tilemask_out, int height, int width, int top) { - const int numblox_W = ceil(((float)(width)) / (offset)); + const int numblox_W = ceil((static_cast(width)) / (offset)); const float DCTnorm = 1.0f / (4 * TS * TS); //for DCT int imin = MAX(0, -top); - int bottom = MIN( top + TS, height); + int bottom = MIN(top + TS, height); int imax = bottom - top; //add row of tiles to output image - for (int i = imin; i < imax; i++) - for (int hblk = 0; hblk < numblox_W; hblk++) { + for (int i = imin; i < imax; ++i) { + for (int hblk = 0; hblk < numblox_W; ++hblk) { int left = (hblk - blkrad) * offset; int right = MIN(left + TS, width); int jmin = MAX(0, -left); int jmax = right - left; int indx = hblk * TS; - for (int j = jmin; j < jmax; j++) { // this loop gets auto vectorized by gcc + for (int j = jmin; j < jmax; ++j) { // this loop gets auto vectorized by gcc Ldetail[top + i][left + j] += tilemask_out[i][j] * bloxrow_L[(indx + i) * TS + j] * DCTnorm; //for DCT } } + } } /* #undef TS @@ -2148,12 +2111,12 @@ float ImProcFunctions::MadMax(float * DataList, int & max, int datalen) int * histo = new int[65536]; //memset(histo, 0, 65536*sizeof(histo)); - for (int i = 0; i < 65536; i++) { + for (int i = 0; i < 65536; ++i) { histo[i] = 0; } //calculate histogram of absolute values of HH wavelet coeffs - for (int i = 0; i < datalen; i++) { + for (int i = 0; i < datalen; ++i) { histo[MAX(0, MIN(65535, abs((int)DataList[i])))]++; } @@ -2162,7 +2125,7 @@ float ImProcFunctions::MadMax(float * DataList, int & max, int datalen) while (count < datalen / 2) { count += histo[median]; - median++; + ++median; } //find max of histogram @@ -2177,11 +2140,11 @@ float ImProcFunctions::MadMax(float * DataList, int & max, int datalen) delete[] histo; // interpolate - return (( (median - 1) + (datalen / 2 - count_) / ((float)(count - count_)) ) / 0.6745); + return (((median - 1) + (datalen / 2 - count_) / (static_cast(count - count_))) / 0.6745); } -float ImProcFunctions::Mad( float * DataList, const int datalen) +float ImProcFunctions::Mad(float * DataList, const int datalen) { //computes Median Absolute Deviation @@ -2189,8 +2152,8 @@ float ImProcFunctions::Mad( float * DataList, const int datalen) int histo[256] ALIGNED64 = {0}; //calculate histogram of absolute values of wavelet coeffs - for (int i = 0; i < datalen; i++) { - histo[min(255, abs((int)DataList[i]))]++; + for (int i = 0; i < datalen; ++i) { + histo[min(255, abs(static_cast(DataList[i])))]++; } //find median of histogram @@ -2198,31 +2161,31 @@ float ImProcFunctions::Mad( float * DataList, const int datalen) while (count < datalen / 2) { count += histo[median]; - median++; + ++median; } int count_ = count - histo[median - 1]; // interpolate - return (( (median - 1) + (datalen / 2 - count_) / ((float)(count - count_)) ) / 0.6745); + return (((median - 1) + (datalen / 2 - count_) / (static_cast(count - count_))) / 0.6745); } -float ImProcFunctions::MadRgb( float * DataList, const int datalen) +float ImProcFunctions::MadRgb(float * DataList, const int datalen) { //computes Median Absolute Deviation //DataList values should mostly have abs val < 65536 because we are in RGB mode int * histo = new int[65536]; - for(int i = 0; i < 65536; i++) { + for (int i = 0; i < 65536; ++i) { histo[i] = 0; } //calculate histogram of absolute values of wavelet coeffs int i; - for (i = 0; i < datalen; i++) { - histo[min(65536, abs((int)DataList[i]))]++; + for (i = 0; i < datalen; ++i) { + histo[min(65535, abs(static_cast(DataList[i])))]++; } //find median of histogram @@ -2230,14 +2193,14 @@ float ImProcFunctions::MadRgb( float * DataList, const int datalen) while (count < datalen / 2) { count += histo[median]; - median++; + ++median; } int count_ = count - histo[median - 1]; // interpolate - delete [] histo; - return (( (median - 1) + (datalen / 2 - count_) / ((float)(count - count_)) ) / 0.6745); + delete[] histo; + return (((median - 1) + (datalen / 2 - count_) / (static_cast(count - count_))) / 0.6745); } @@ -2249,7 +2212,7 @@ void ImProcFunctions::Noise_residualAB(wavelet_decomposition &WaveletCoeffs_ab, float madC; float maxresid = 0.f; - for (int lvl = 0; lvl < maxlvl; lvl++) { + for (int lvl = 0; lvl < maxlvl; ++lvl) { // compute median absolute deviation (MAD) of detail coefficients as robust noise estimator int Wlvl_ab = WaveletCoeffs_ab.level_W(lvl); @@ -2257,8 +2220,8 @@ void ImProcFunctions::Noise_residualAB(wavelet_decomposition &WaveletCoeffs_ab, float ** WavCoeffs_ab = WaveletCoeffs_ab.level_coeffs(lvl); - for (int dir = 1; dir < 4; dir++) { - if(denoiseMethodRgb) { + for (int dir = 1; dir < 4; ++dir) { + if (denoiseMethodRgb) { madC = SQR(MadRgb(WavCoeffs_ab[dir], Wlvl_ab * Hlvl_ab)); } else { madC = SQR(Mad(WavCoeffs_ab[dir], Wlvl_ab * Hlvl_ab)); @@ -2266,7 +2229,7 @@ void ImProcFunctions::Noise_residualAB(wavelet_decomposition &WaveletCoeffs_ab, resid += madC; - if(madC > maxresid ) { + if (madC > maxresid) { maxresid = madC; } } @@ -2283,19 +2246,19 @@ SSEFUNCTION bool ImProcFunctions::WaveletDenoiseAll_BiShrinkL(wavelet_decomposit int maxWL = 0, maxHL = 0; - for (int lvl = 0; lvl < maxlvl; lvl++) { - if(WaveletCoeffs_L.level_W(lvl) > maxWL) { + for (int lvl = 0; lvl < maxlvl; ++lvl) { + if (WaveletCoeffs_L.level_W(lvl) > maxWL) { maxWL = WaveletCoeffs_L.level_W(lvl); } - if(WaveletCoeffs_L.level_H(lvl) > maxHL) { + if (WaveletCoeffs_L.level_H(lvl) > maxHL) { maxHL = WaveletCoeffs_L.level_H(lvl); } } bool memoryAllocationFailed = false; #ifdef _RT_NESTED_OPENMP - #pragma omp parallel num_threads(denoiseNestedLevels) if(denoiseNestedLevels>1) + #pragma omp parallel num_threads(denoiseNestedLevels) if (denoiseNestedLevels>1) #endif { float *buffer[3]; @@ -2303,18 +2266,18 @@ SSEFUNCTION bool ImProcFunctions::WaveletDenoiseAll_BiShrinkL(wavelet_decomposit buffer[1] = new (std::nothrow) float[maxWL * maxHL + 64]; buffer[2] = new (std::nothrow) float[maxWL * maxHL + 96]; - if(buffer[0] == NULL || buffer[1] == NULL || buffer[2] == NULL) { + if (buffer[0] == nullptr || buffer[1] == nullptr || buffer[2] == nullptr) { memoryAllocationFailed = true; } - if(!memoryAllocationFailed) { + if (!memoryAllocationFailed) { #ifdef _RT_NESTED_OPENMP #pragma omp for schedule(dynamic) collapse(2) #endif for (int lvl = maxlvl - 1; lvl >= 0; lvl--) { //for levels less than max, use level diff to make edge mask - for (int dir = 1; dir < 4; dir++) { + for (int dir = 1; dir < 4; ++dir) { int Wlvl_L = WaveletCoeffs_L.level_W(lvl); int Hlvl_L = WaveletCoeffs_L.level_H(lvl); @@ -2323,7 +2286,7 @@ SSEFUNCTION bool ImProcFunctions::WaveletDenoiseAll_BiShrinkL(wavelet_decomposit if (lvl == maxlvl - 1) { float vari[4]; int edge = 0; - ShrinkAllL(WaveletCoeffs_L, buffer, lvl, dir, noisevarlum, madL[lvl], NULL, edge ); + ShrinkAllL(WaveletCoeffs_L, buffer, lvl, dir, noisevarlum, madL[lvl], nullptr, edge); } else { //simple wavelet shrinkage float * sfave = buffer[0] + 32; @@ -2335,7 +2298,7 @@ SSEFUNCTION bool ImProcFunctions::WaveletDenoiseAll_BiShrinkL(wavelet_decomposit float levelFactor = mad_Lr * 5.f / (lvl + 1); #ifdef __SSE2__ __m128 mad_Lv; - __m128 ninev = _mm_set1_ps( 9.0f ); + __m128 ninev = _mm_set1_ps(9.0f); __m128 epsv = _mm_set1_ps(eps); __m128 mag_Lv; __m128 levelFactorv = _mm_set1_ps(levelFactor); @@ -2344,23 +2307,24 @@ SSEFUNCTION bool ImProcFunctions::WaveletDenoiseAll_BiShrinkL(wavelet_decomposit for (coeffloc_L = 0; coeffloc_L < Hlvl_L * Wlvl_L - 3; coeffloc_L += 4) { mad_Lv = LVFU(noisevarlum[coeffloc_L]) * levelFactorv; mag_Lv = SQRV(LVFU(WavCoeffs_L[dir][coeffloc_L])); - _mm_storeu_ps(&sfave[coeffloc_L], mag_Lv / ( mag_Lv + mad_Lv * xexpf(-mag_Lv / (mad_Lv * ninev) ) + epsv)); + _mm_storeu_ps(&sfave[coeffloc_L], mag_Lv / (mag_Lv + mad_Lv * xexpf(-mag_Lv / (mad_Lv * ninev)) + epsv)); } - for (; coeffloc_L < Hlvl_L * Wlvl_L; coeffloc_L++) { + for (; coeffloc_L < Hlvl_L * Wlvl_L; ++coeffloc_L) { float mag_L = SQR(WavCoeffs_L[dir][coeffloc_L]); sfave[coeffloc_L] = mag_L / (mag_L + levelFactor * noisevarlum[coeffloc_L] * xexpf(-mag_L / (9.f * levelFactor * noisevarlum[coeffloc_L])) + eps); } #else - for (int i = 0; i < Hlvl_L; i++) - for (int j = 0; j < Wlvl_L; j++) { + for (int i = 0; i < Hlvl_L; ++i) { + for (int j = 0; j < Wlvl_L; ++j) { int coeffloc_L = i * Wlvl_L + j; float mag_L = SQR(WavCoeffs_L[dir][coeffloc_L]); sfave[coeffloc_L] = mag_L / (mag_L + levelFactor * noisevarlum[coeffloc_L] * xexpf(-mag_L / (9.f * levelFactor * noisevarlum[coeffloc_L])) + eps); } + } #endif boxblur(sfave, sfaved, blurBuffer, lvl + 2, lvl + 2, Wlvl_L, Hlvl_L); //increase smoothness by locally averaging shrinkage @@ -2376,7 +2340,7 @@ SSEFUNCTION bool ImProcFunctions::WaveletDenoiseAll_BiShrinkL(wavelet_decomposit } // few remaining pixels - for (; coeffloc_L < Hlvl_L * Wlvl_L; coeffloc_L++) { + for (; coeffloc_L < Hlvl_L * Wlvl_L; ++coeffloc_L) { float sf_L = sfave[coeffloc_L]; //use smoothed shrinkage unless local shrinkage is much less WavCoeffs_L[dir][coeffloc_L] *= (SQR(sfaved[coeffloc_L]) + SQR(sf_L)) / (sfaved[coeffloc_L] + sf_L + eps); @@ -2384,13 +2348,14 @@ SSEFUNCTION bool ImProcFunctions::WaveletDenoiseAll_BiShrinkL(wavelet_decomposit #else - for (int i = 0; i < Hlvl_L; i++) - for (int j = 0; j < Wlvl_L; j++) { + for (int i = 0; i < Hlvl_L; ++i) { + for (int j = 0; j < Wlvl_L; ++j) { int coeffloc_L = i * Wlvl_L + j; float sf_L = sfave[coeffloc_L]; //use smoothed shrinkage unless local shrinkage is much less WavCoeffs_L[dir][coeffloc_L] *= (SQR(sfaved[coeffloc_L]) + SQR(sf_L)) / (sfaved[coeffloc_L] + sf_L + eps); }//now luminance coeffs are denoised + } #endif } @@ -2398,10 +2363,11 @@ SSEFUNCTION bool ImProcFunctions::WaveletDenoiseAll_BiShrinkL(wavelet_decomposit } } - for(int i = 2; i >= 0; i--) - if(buffer[i] != NULL) { - delete [] buffer[i]; + for (int i = 2; i >= 0; i--) { + if (buffer[i] != nullptr) { + delete[] buffer[i]; } + } } return (!memoryAllocationFailed); @@ -2412,7 +2378,7 @@ SSEFUNCTION bool ImProcFunctions::WaveletDenoiseAll_BiShrinkAB(wavelet_decomposi { int maxlvl = WaveletCoeffs_L.maxlevel(); - if(autoch && noisevar_ab <= 0.001f) { + if (autoch && noisevar_ab <= 0.001f) { noisevar_ab = 0.02f; } @@ -2420,19 +2386,19 @@ SSEFUNCTION bool ImProcFunctions::WaveletDenoiseAll_BiShrinkAB(wavelet_decomposi int maxWL = 0, maxHL = 0; - for (int lvl = 0; lvl < maxlvl; lvl++) { - if(WaveletCoeffs_L.level_W(lvl) > maxWL) { + for (int lvl = 0; lvl < maxlvl; ++lvl) { + if (WaveletCoeffs_L.level_W(lvl) > maxWL) { maxWL = WaveletCoeffs_L.level_W(lvl); } - if(WaveletCoeffs_L.level_H(lvl) > maxHL) { + if (WaveletCoeffs_L.level_H(lvl) > maxHL) { maxHL = WaveletCoeffs_L.level_H(lvl); } } bool memoryAllocationFailed = false; #ifdef _RT_NESTED_OPENMP - #pragma omp parallel num_threads(denoiseNestedLevels) if(denoiseNestedLevels>1) + #pragma omp parallel num_threads(denoiseNestedLevels) if (denoiseNestedLevels>1) #endif { float *buffer[3]; @@ -2440,25 +2406,25 @@ SSEFUNCTION bool ImProcFunctions::WaveletDenoiseAll_BiShrinkAB(wavelet_decomposi buffer[1] = new (std::nothrow) float[maxWL * maxHL + 64]; buffer[2] = new (std::nothrow) float[maxWL * maxHL + 96]; - if(buffer[0] == NULL || buffer[1] == NULL || buffer[2] == NULL) { + if (buffer[0] == nullptr || buffer[1] == nullptr || buffer[2] == nullptr) { memoryAllocationFailed = true; } - if(!memoryAllocationFailed) { + if (!memoryAllocationFailed) { #ifdef _RT_NESTED_OPENMP #pragma omp for schedule(dynamic) collapse(2) #endif - for (int lvl = 0; lvl < maxlvl; lvl++) { - for (int dir = 1; dir < 4; dir++) { + for (int lvl = 0; lvl < maxlvl; ++lvl) { + for (int dir = 1; dir < 4; ++dir) { // compute median absolute deviation (MAD) of detail coefficients as robust noise estimator int Wlvl_ab = WaveletCoeffs_ab.level_W(lvl); int Hlvl_ab = WaveletCoeffs_ab.level_H(lvl); float ** WavCoeffs_ab = WaveletCoeffs_ab.level_coeffs(lvl); - if(!denoiseMethodRgb) { + if (!denoiseMethodRgb) { madab[lvl][dir - 1] = SQR(Mad(WavCoeffs_ab[dir], Wlvl_ab * Hlvl_ab)); } else { madab[lvl][dir - 1] = SQR(MadRgb(WavCoeffs_ab[dir], Wlvl_ab * Hlvl_ab)); @@ -2471,7 +2437,7 @@ SSEFUNCTION bool ImProcFunctions::WaveletDenoiseAll_BiShrinkAB(wavelet_decomposi #endif for (int lvl = maxlvl - 1; lvl >= 0; lvl--) { //for levels less than max, use level diff to make edge mask - for (int dir = 1; dir < 4; dir++) { + for (int dir = 1; dir < 4; ++dir) { int Wlvl_ab = WaveletCoeffs_ab.level_W(lvl); int Hlvl_ab = WaveletCoeffs_ab.level_H(lvl); @@ -2508,7 +2474,7 @@ SSEFUNCTION bool ImProcFunctions::WaveletDenoiseAll_BiShrinkAB(wavelet_decomposi } // few remaining pixels - for (; coeffloc_ab < Hlvl_ab * Wlvl_ab; coeffloc_ab++) { + for (; coeffloc_ab < Hlvl_ab * Wlvl_ab; ++coeffloc_ab) { float mag_L = SQR(WavCoeffs_L[dir][coeffloc_ab ]); float mag_ab = SQR(WavCoeffs_ab[dir][coeffloc_ab]); WavCoeffs_ab[dir][coeffloc_ab] *= SQR(1.f - xexpf(-(mag_ab / (noisevarchrom[coeffloc_ab] * mad_abr)) - (mag_L / (9.f * mad_Lr)))/*satfactor_a*/); @@ -2516,8 +2482,8 @@ SSEFUNCTION bool ImProcFunctions::WaveletDenoiseAll_BiShrinkAB(wavelet_decomposi #else - for (int i = 0; i < Hlvl_ab; i++) { - for (int j = 0; j < Wlvl_ab; j++) { + for (int i = 0; i < Hlvl_ab; ++i) { + for (int j = 0; j < Wlvl_ab; ++j) { int coeffloc_ab = i * Wlvl_ab + j; float mag_L = SQR(WavCoeffs_L[dir][coeffloc_ab ]); @@ -2536,10 +2502,11 @@ SSEFUNCTION bool ImProcFunctions::WaveletDenoiseAll_BiShrinkAB(wavelet_decomposi } } - for(int i = 2; i >= 0; i--) - if(buffer[i] != NULL) { - delete [] buffer[i]; + for (int i = 2; i >= 0; i--) { + if (buffer[i] != nullptr) { + delete[] buffer[i]; } + } } return (!memoryAllocationFailed); @@ -2552,25 +2519,25 @@ bool ImProcFunctions::WaveletDenoiseAllL(wavelet_decomposition &WaveletCoeffs_L, int maxlvl = min(WaveletCoeffs_L.maxlevel(), 5); - if(edge == 1) { + if (edge == 1) { maxlvl = 4; //for refine denoise edge wavelet } int maxWL = 0, maxHL = 0; - for (int lvl = 0; lvl < maxlvl; lvl++) { - if(WaveletCoeffs_L.level_W(lvl) > maxWL) { + for (int lvl = 0; lvl < maxlvl; ++lvl) { + if (WaveletCoeffs_L.level_W(lvl) > maxWL) { maxWL = WaveletCoeffs_L.level_W(lvl); } - if(WaveletCoeffs_L.level_H(lvl) > maxHL) { + if (WaveletCoeffs_L.level_H(lvl) > maxHL) { maxHL = WaveletCoeffs_L.level_H(lvl); } } bool memoryAllocationFailed = false; #ifdef _RT_NESTED_OPENMP - #pragma omp parallel num_threads(denoiseNestedLevels) if(denoiseNestedLevels>1) + #pragma omp parallel num_threads(denoiseNestedLevels) if (denoiseNestedLevels>1) #endif { float *buffer[4]; @@ -2579,26 +2546,27 @@ bool ImProcFunctions::WaveletDenoiseAllL(wavelet_decomposition &WaveletCoeffs_L, buffer[2] = new (std::nothrow) float[maxWL * maxHL + 96]; buffer[3] = new (std::nothrow) float[maxWL * maxHL + 128]; - if(buffer[0] == NULL || buffer[1] == NULL || buffer[2] == NULL || buffer[3] == NULL) { + if (buffer[0] == nullptr || buffer[1] == nullptr || buffer[2] == nullptr || buffer[3] == nullptr) { memoryAllocationFailed = true; } - if(!memoryAllocationFailed) { + if (!memoryAllocationFailed) { #ifdef _RT_NESTED_OPENMP #pragma omp for schedule(dynamic) collapse(2) #endif - for (int lvl = 0; lvl < maxlvl; lvl++) { - for (int dir = 1; dir < 4; dir++) { + for (int lvl = 0; lvl < maxlvl; ++lvl) { + for (int dir = 1; dir < 4; ++dir) { ShrinkAllL(WaveletCoeffs_L, buffer, lvl, dir, noisevarlum, madL[lvl], vari, edge); } } } - for(int i = 3; i >= 0; i--) - if(buffer[i] != NULL) { - delete [] buffer[i]; + for (int i = 3; i >= 0; i--) { + if (buffer[i] != nullptr) { + delete[] buffer[i]; } + } } return (!memoryAllocationFailed); } @@ -2612,19 +2580,19 @@ bool ImProcFunctions::WaveletDenoiseAllAB(wavelet_decomposition &WaveletCoeffs_L int maxlvl = WaveletCoeffs_L.maxlevel(); int maxWL = 0, maxHL = 0; - for (int lvl = 0; lvl < maxlvl; lvl++) { - if(WaveletCoeffs_L.level_W(lvl) > maxWL) { + for (int lvl = 0; lvl < maxlvl; ++lvl) { + if (WaveletCoeffs_L.level_W(lvl) > maxWL) { maxWL = WaveletCoeffs_L.level_W(lvl); } - if(WaveletCoeffs_L.level_H(lvl) > maxHL) { + if (WaveletCoeffs_L.level_H(lvl) > maxHL) { maxHL = WaveletCoeffs_L.level_H(lvl); } } bool memoryAllocationFailed = false; #ifdef _RT_NESTED_OPENMP - #pragma omp parallel num_threads(denoiseNestedLevels) if(denoiseNestedLevels>1) + #pragma omp parallel num_threads(denoiseNestedLevels) if (denoiseNestedLevels>1) #endif { float *buffer[3]; @@ -2632,26 +2600,27 @@ bool ImProcFunctions::WaveletDenoiseAllAB(wavelet_decomposition &WaveletCoeffs_L buffer[1] = new (std::nothrow) float[maxWL * maxHL + 64]; buffer[2] = new (std::nothrow) float[maxWL * maxHL + 96]; - if(buffer[0] == NULL || buffer[1] == NULL || buffer[2] == NULL) { + if (buffer[0] == nullptr || buffer[1] == nullptr || buffer[2] == nullptr) { memoryAllocationFailed = true; } - if(!memoryAllocationFailed) { + if (!memoryAllocationFailed) { #ifdef _RT_NESTED_OPENMP #pragma omp for schedule(dynamic) collapse(2) #endif - for (int lvl = 0; lvl < maxlvl; lvl++) { - for (int dir = 1; dir < 4; dir++) { + for (int lvl = 0; lvl < maxlvl; ++lvl) { + for (int dir = 1; dir < 4; ++dir) { ShrinkAllAB(WaveletCoeffs_L, WaveletCoeffs_ab, buffer, lvl, dir, noisevarchrom, noisevar_ab, useNoiseCCurve, autoch, denoiseMethodRgb, madL[lvl]); } } } - for(int i = 2; i >= 0; i--) - if(buffer[i] != NULL) { - delete [] buffer[i]; + for (int i = 2; i >= 0; i--) { + if (buffer[i] != nullptr) { + delete[] buffer[i]; } + } } return (!memoryAllocationFailed); } @@ -2661,7 +2630,7 @@ bool ImProcFunctions::WaveletDenoiseAllAB(wavelet_decomposition &WaveletCoeffs_L SSEFUNCTION void ImProcFunctions::ShrinkAllL(wavelet_decomposition &WaveletCoeffs_L, float **buffer, int level, int dir, - float *noisevarlum, float * madL, float * vari, int edge ) + float *noisevarlum, float * madL, float * vari, int edge) { //simple wavelet shrinkage @@ -2678,38 +2647,38 @@ SSEFUNCTION void ImProcFunctions::ShrinkAllL(wavelet_decomposition &WaveletCoeff // printf("OK lev=%d\n",level); float mad_L = madL[dir - 1] ; - if(edge == 1) { + if (edge == 1) { noisevarlum = blurBuffer; // we need one buffer, but fortunately we don't have to allocate a new one because we can use blurBuffer - for (int i = 0; i < W_L * H_L; i++) { + for (int i = 0; i < W_L * H_L; ++i) { noisevarlum[i] = vari[level]; } } - float levelFactor = mad_L * 5.f / (float)(level + 1); + float levelFactor = mad_L * 5.f / static_cast(level + 1); #ifdef __SSE2__ __m128 magv; __m128 levelFactorv = _mm_set1_ps(levelFactor); __m128 mad_Lv; - __m128 ninev = _mm_set1_ps( 9.0f ); - __m128 epsv = _mm_set1_ps( eps ); + __m128 ninev = _mm_set1_ps(9.0f); + __m128 epsv = _mm_set1_ps(eps); int i; for (i = 0; i < W_L * H_L - 3; i += 4) { mad_Lv = LVFU(noisevarlum[i]) * levelFactorv; magv = SQRV(LVFU(WavCoeffs_L[dir][i])); - _mm_storeu_ps( &sfave[i], magv / (magv + mad_Lv * xexpf(-magv / (ninev * mad_Lv)) + epsv)); + _mm_storeu_ps(&sfave[i], magv / (magv + mad_Lv * xexpf(-magv / (ninev * mad_Lv)) + epsv)); } // few remaining pixels - for (; i < W_L * H_L; i++) { + for (; i < W_L * H_L; ++i) { float mag = SQR(WavCoeffs_L[dir][i]); sfave[i] = mag / (mag + levelFactor * noisevarlum[i] * xexpf(-mag / (9 * levelFactor * noisevarlum[i])) + eps); } #else - for (int i = 0; i < W_L * H_L; i++) { + for (int i = 0; i < W_L * H_L; ++i) { float mag = SQR(WavCoeffs_L[dir][i]); float shrinkfactor = mag / (mag + levelFactor * noisevarlum[i] * xexpf(-mag / (9 * levelFactor * noisevarlum[i])) + eps); @@ -2725,11 +2694,11 @@ SSEFUNCTION void ImProcFunctions::ShrinkAllL(wavelet_decomposition &WaveletCoeff for (i = 0; i < W_L * H_L - 3; i += 4) { sfv = LVFU(sfave[i]); //use smoothed shrinkage unless local shrinkage is much less - _mm_storeu_ps( &WavCoeffs_L[dir][i], _mm_loadu_ps( &WavCoeffs_L[dir][i]) * (SQRV( LVFU(sfaved[i] )) + SQRV(sfv)) / (LVFU(sfaved[i]) + sfv + epsv)); + _mm_storeu_ps(&WavCoeffs_L[dir][i], _mm_loadu_ps(&WavCoeffs_L[dir][i]) * (SQRV(LVFU(sfaved[i])) + SQRV(sfv)) / (LVFU(sfaved[i]) + sfv + epsv)); } // few remaining pixels - for (; i < W_L * H_L; i++) { + for (; i < W_L * H_L; ++i) { float sf = sfave[i]; //use smoothed shrinkage unless local shrinkage is much less @@ -2738,7 +2707,7 @@ SSEFUNCTION void ImProcFunctions::ShrinkAllL(wavelet_decomposition &WaveletCoeff #else - for (int i = 0; i < W_L * H_L; i++) { + for (int i = 0; i < W_L * H_L; ++i) { float sf = sfave[i]; //use smoothed shrinkage unless local shrinkage is much less @@ -2752,13 +2721,13 @@ SSEFUNCTION void ImProcFunctions::ShrinkAllL(wavelet_decomposition &WaveletCoeff SSEFUNCTION void ImProcFunctions::ShrinkAllAB(wavelet_decomposition &WaveletCoeffs_L, wavelet_decomposition &WaveletCoeffs_ab, float **buffer, int level, int dir, float *noisevarchrom, float noisevar_ab, const bool useNoiseCCurve, bool autoch, - bool denoiseMethodRgb, float * madL, float * madaab, bool madCalculated ) + bool denoiseMethodRgb, float * madL, float * madaab, bool madCalculated) { //simple wavelet shrinkage const float eps = 0.01f; - if(autoch && noisevar_ab <= 0.001f) { + if (autoch && noisevar_ab <= 0.001f) { noisevar_ab = 0.02f; } @@ -2775,10 +2744,10 @@ SSEFUNCTION void ImProcFunctions::ShrinkAllAB(wavelet_decomposition &WaveletCoef float madab; float mad_L = madL[dir - 1]; - if(madCalculated) { + if (madCalculated) { madab = madaab[dir - 1]; } else { - if(!denoiseMethodRgb) { + if (!denoiseMethodRgb) { madab = SQR(Mad(WavCoeffs_ab[dir], W_ab * H_ab)); } else { madab = SQR(MadRgb(WavCoeffs_ab[dir], W_ab * H_ab)); @@ -2806,7 +2775,7 @@ SSEFUNCTION void ImProcFunctions::ShrinkAllAB(wavelet_decomposition &WaveletCoef } // few remaining pixels - for (; coeffloc_ab < H_ab * W_ab; coeffloc_ab++) { + for (; coeffloc_ab < H_ab * W_ab; ++coeffloc_ab) { float mag_L = SQR(WavCoeffs_L[dir][coeffloc_ab]); float mag_ab = SQR(WavCoeffs_ab[dir][coeffloc_ab]); sfaveab[coeffloc_ab] = (1.f - xexpf(-(mag_ab / (noisevarchrom[coeffloc_ab] * madab)) - (mag_L / (9.f * mad_L)))); @@ -2814,8 +2783,8 @@ SSEFUNCTION void ImProcFunctions::ShrinkAllAB(wavelet_decomposition &WaveletCoef #else - for (int i = 0; i < H_ab; i++) { - for (int j = 0; j < W_ab; j++) { + for (int i = 0; i < H_ab; ++i) { + for (int j = 0; j < W_ab; ++j) { int coeffloc_ab = i * W_ab + j; float mag_L = SQR(WavCoeffs_L[dir][coeffloc_ab]); float mag_ab = SQR(WavCoeffs_ab[dir][coeffloc_ab]); @@ -2836,11 +2805,11 @@ SSEFUNCTION void ImProcFunctions::ShrinkAllAB(wavelet_decomposition &WaveletCoef sfaveabv = LVFU(sfaveabd[coeffloc_ab]); //use smoothed shrinkage unless local shrinkage is much less - _mm_storeu_ps( &WavCoeffs_ab[dir][coeffloc_ab], LVFU(WavCoeffs_ab[dir][coeffloc_ab]) * (SQRV(sfaveabv) + SQRV(sfabv)) / (sfaveabv + sfabv + epsv)); + _mm_storeu_ps(&WavCoeffs_ab[dir][coeffloc_ab], LVFU(WavCoeffs_ab[dir][coeffloc_ab]) * (SQRV(sfaveabv) + SQRV(sfabv)) / (sfaveabv + sfabv + epsv)); } // few remaining pixels - for (; coeffloc_ab < H_ab * W_ab; coeffloc_ab++) { + for (; coeffloc_ab < H_ab * W_ab; ++coeffloc_ab) { //modification Jacques feb 2013 float sfab = sfaveab[coeffloc_ab]; @@ -2850,8 +2819,8 @@ SSEFUNCTION void ImProcFunctions::ShrinkAllAB(wavelet_decomposition &WaveletCoef #else - for (int i = 0; i < H_ab; i++) { - for (int j = 0; j < W_ab; j++) { + for (int i = 0; i < H_ab; ++i) { + for (int j = 0; j < W_ab; ++j) { int coeffloc_ab = i * W_ab + j; float sfab = sfaveab[coeffloc_ab]; @@ -2872,7 +2841,7 @@ SSEFUNCTION void ImProcFunctions::ShrinkAll_info(float ** WavCoeffs_a, float ** { //simple wavelet shrinkage - if(lvl == 1) { //only one time + if (lvl == 1) { //only one time float chro = 0.f; float dev = 0.f; float devL = 0.f; @@ -2884,56 +2853,56 @@ SSEFUNCTION void ImProcFunctions::ShrinkAll_info(float ** WavCoeffs_a, float ** float skin_c = 0.f; int nsk = 0; - for (int i = 0; i < H_ab; i++) { - for (int j = 0; j < W_ab; j++) { + for (int i = 0; i < H_ab; ++i) { + for (int j = 0; j < W_ab; ++j) { chro += noisevarchrom[i][j]; - nc++; + ++nc; dev += SQR(noisevarchrom[i][j] - (chro / nc)); - if(noisevarhue[i][j] > -0.8f && noisevarhue[i][j] < 2.0f && noisevarchrom[i][j] > 10000.f) {//saturated red yellow + if (noisevarhue[i][j] > -0.8f && noisevarhue[i][j] < 2.0f && noisevarchrom[i][j] > 10000.f) {//saturated red yellow red_yel += noisevarchrom[i][j]; - nry++; + ++nry; } - if(noisevarhue[i][j] > 0.f && noisevarhue[i][j] < 1.6f && noisevarchrom[i][j] < 10000.f) {//skin + if (noisevarhue[i][j] > 0.f && noisevarhue[i][j] < 1.6f && noisevarchrom[i][j] < 10000.f) {//skin skin_c += noisevarchrom[i][j]; - nsk++; + ++nsk; } lume += noisevarlum[i][j]; - nL++; + ++nL; devL += SQR(noisevarlum[i][j] - (lume / nL)); } } - if(nc > 0) { + if (nc > 0) { chromina = chro / nc; sigma = sqrt(dev / nc); - nsknc = (float)nsk / (float)nc; + nsknc = static_cast(nsk) / static_cast(nc); } else { - nsknc = (float)nsk; + nsknc = static_cast(nsk); } - if(nL > 0) { + if (nL > 0) { lumema = lume / nL; sigma_L = sqrt(devL / nL); } - if(nry > 0) { + if (nry > 0) { redyel = red_yel / nry; } - if(nsk > 0) { + if (nsk > 0) { skinc = skin_c / nsk; } } - const float reduc = (schoice == 2) ? (float) settings->nrhigh : 1.f; + const float reduc = (schoice == 2) ? static_cast( settings->nrhigh) : 1.f; - for (int dir = 1; dir < 4; dir++) { + for (int dir = 1; dir < 4; ++dir) { float mada, madb; - if(!denoiseMethodRgb) { + if (!denoiseMethodRgb) { mada = SQR(Mad(WavCoeffs_a[dir], W_ab * H_ab)); } else { mada = SQR(MadRgb(WavCoeffs_a[dir], W_ab * H_ab)); @@ -2941,18 +2910,18 @@ SSEFUNCTION void ImProcFunctions::ShrinkAll_info(float ** WavCoeffs_a, float ** chred += mada; - if(mada > maxchred) { + if (mada > maxchred) { maxchred = mada; } - if(mada < minchred) { + if (mada < minchred) { minchred = mada; } maxredaut = sqrt(reduc * maxchred); minredaut = sqrt(reduc * minchred); - if(!denoiseMethodRgb) { + if (!denoiseMethodRgb) { madb = SQR(Mad(WavCoeffs_b[dir], W_ab * H_ab)); } else { madb = SQR(MadRgb(WavCoeffs_b[dir], W_ab * H_ab)); @@ -2960,11 +2929,11 @@ SSEFUNCTION void ImProcFunctions::ShrinkAll_info(float ** WavCoeffs_a, float ** chblue += madb; - if(madb > maxchblue) { + if (madb > maxchblue) { maxchblue = madb; } - if(madb < minchblue) { + if (madb < minchblue) { minchblue = madb; } @@ -2972,7 +2941,7 @@ SSEFUNCTION void ImProcFunctions::ShrinkAll_info(float ** WavCoeffs_a, float ** minblueaut = sqrt(reduc * minchblue); chau += (mada + madb); - nb++; + ++nb; //here evaluation of automatic chaut = sqrt(reduc * chau / (nb + nb)); redaut = sqrt(reduc * chred / nb); @@ -2985,12 +2954,12 @@ SSEFUNCTION void ImProcFunctions::ShrinkAll_info(float ** WavCoeffs_a, float ** void ImProcFunctions::WaveletDenoiseAll_info(int levwav, wavelet_decomposition &WaveletCoeffs_a, wavelet_decomposition &WaveletCoeffs_b, float **noisevarlum, float **noisevarchrom, float **noisevarhue, int width, int height, float noisevar_abr, float noisevar_abb, LabImage * noi, float &chaut, int &Nb, float &redaut, float &blueaut, float &maxredaut, float &maxblueaut, float &minredaut, float &minblueaut, int schoice, bool autoch, - float &chromina, float &sigma, float &lumema, float &sigma_L, float &redyel, float &skinc, float &nsknc, float &maxchred, float &maxchblue, float &minchred, float &minchblue, int &nb, float &chau, float &chred, float &chblue, bool denoiseMethodRgb, bool multiThread ) + float &chromina, float &sigma, float &lumema, float &sigma_L, float &redyel, float &skinc, float &nsknc, float &maxchred, float &maxchblue, float &minchred, float &minchblue, int &nb, float &chau, float &chred, float &chblue, bool denoiseMethodRgb, bool multiThread) { int maxlvl = levwav; - for (int lvl = 0; lvl < maxlvl; lvl++) { + for (int lvl = 0; lvl < maxlvl; ++lvl) { int Wlvl_ab = WaveletCoeffs_a.level_W(lvl); int Hlvl_ab = WaveletCoeffs_a.level_H(lvl); @@ -3002,7 +2971,7 @@ void ImProcFunctions::WaveletDenoiseAll_info(int levwav, wavelet_decomposition & ShrinkAll_info(WavCoeffs_a, WavCoeffs_b, lvl, Wlvl_ab, Hlvl_ab, skip_ab, noisevarlum, noisevarchrom, noisevarhue, width, height, noisevar_abr, noisevar_abb, noi, chaut, Nb, redaut, blueaut, maxredaut, maxblueaut, minredaut, minblueaut, - autoch, schoice, lvl, chromina, sigma, lumema, sigma_L, redyel, skinc, nsknc, maxchred, maxchblue, minchred, minchblue, nb, chau, chred, chblue, denoiseMethodRgb, multiThread ); + autoch, schoice, lvl, chromina, sigma, lumema, sigma_L, redyel, skinc, nsknc, maxchred, maxchblue, minchred, minchblue, nb, chau, chred, chblue, denoiseMethodRgb, multiThread); } } @@ -3012,24 +2981,24 @@ void ImProcFunctions::RGB_denoise_infoGamCurve(const procparams::DirPyrDenoisePa gam = dnparams.gamma; gamthresh = 0.001f; - if(!isRAW) {//reduce gamma under 1 for Lab mode ==> TIF and JPG - if(gam < 1.9f) { + if (!isRAW) {//reduce gamma under 1 for Lab mode ==> TIF and JPG + if (gam < 1.9f) { gam = 1.f - (1.9f - gam) / 3.f; //minimum gamma 0.7 } else if (gam >= 1.9f && gam <= 3.f) { gam = (1.4f / 1.1f) * gam - 1.41818f; } } - gamslope = exp(log((double)gamthresh) / gam) / gamthresh; + gamslope = exp(log(static_cast(gamthresh)) / gam) / gamthresh; bool denoiseMethodRgb = (dnparams.dmethod == "RGB"); - if(denoiseMethodRgb) { - for (int i = 0; i < 65536; i++) { - gamcurve[i] = (Color::gamma((double)i / 65535.0, gam, gamthresh, gamslope, 1.0, 0.0)) * 32768.0f; + if (denoiseMethodRgb) { + for (int i = 0; i < 65536; ++i) { + gamcurve[i] = (Color::gamma(static_cast(i) / 65535.0, gam, gamthresh, gamslope, 1.0, 0.0)) * 32768.0f; } } else { - for (int i = 0; i < 65536; i++) { - gamcurve[i] = (Color::gamman((double)i / 65535.0, gam)) * 32768.0f; + for (int i = 0; i < 65536; ++i) { + gamcurve[i] = (Color::gamman(static_cast(i) / 65535.0, gam)) * 32768.0f; } } } @@ -3040,7 +3009,7 @@ void ImProcFunctions::calcautodn_info (float &chaut, float &delta, int Nb, int l float reducdelta = 1.f; if (params->dirpyrDenoise.smethod == "shalbi") { - reducdelta = (float)settings->nrhigh; + reducdelta = static_cast(settings->nrhigh); } chaut = (chaut * Nb - maxmax) / (Nb - 1); //suppress maximum for chaut calcul @@ -3089,8 +3058,8 @@ void ImProcFunctions::calcautodn_info (float &chaut, float &delta, int Nb, int l } } - if(levaut == 0) { //Low denoise - if(chaut > 300.f) { + if (levaut == 0) { //Low denoise + if (chaut > 300.f) { chaut = 0.714286f * chaut + 85.71428f; } } @@ -3099,15 +3068,15 @@ void ImProcFunctions::calcautodn_info (float &chaut, float &delta, int Nb, int l delta *= reducdelta; if (lissage == 1 || lissage == 2) { - if (chaut < 200.f && delta < 200.f ) { + if (chaut < 200.f && delta < 200.f) { delta *= 0.95f; - } else if (chaut < 200.f && delta < 400.f ) { + } else if (chaut < 200.f && delta < 400.f) { delta *= 0.5f; - } else if (chaut < 200.f && delta >= 400.f ) { + } else if (chaut < 200.f && delta >= 400.f) { delta = 200.f; - } else if (chaut < 400.f && delta < 400.f ) { + } else if (chaut < 400.f && delta < 400.f) { delta *= 0.4f; - } else if (chaut < 400.f && delta >= 400.f ) { + } else if (chaut < 400.f && delta >= 400.f) { delta = 120.f; } else if (chaut < 550.f) { delta *= 0.15f; @@ -3137,15 +3106,15 @@ void ImProcFunctions::calcautodn_info (float &chaut, float &delta, int Nb, int l } if (lissage == 0) { - if (chaut < 200.f && delta < 200.f ) { + if (chaut < 200.f && delta < 200.f) { delta *= 0.95f; - } else if (chaut < 200.f && delta < 400.f ) { + } else if (chaut < 200.f && delta < 400.f) { delta *= 0.7f; - } else if (chaut < 200.f && delta >= 400.f ) { + } else if (chaut < 200.f && delta >= 400.f) { delta = 280.f; - } else if (chaut < 400.f && delta < 400.f ) { + } else if (chaut < 400.f && delta < 400.f) { delta *= 0.6f; - } else if (chaut < 400.f && delta >= 400.f ) { + } else if (chaut < 400.f && delta >= 400.f) { delta = 200.f; } else if (chaut < 550.f) { delta *= 0.3f; @@ -3199,28 +3168,28 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise_info(Imagefloat * src, Imagefloat lumcalc = new float*[hei]; - for (int i = 0; i < hei; i++) { + for (int i = 0; i < hei; ++i) { lumcalc[i] = new float[wid]; } acalc = new float*[hei]; - for (int i = 0; i < hei; i++) { + for (int i = 0; i < hei; ++i) { acalc[i] = new float[wid]; } bcalc = new float*[hei]; - for (int i = 0; i < hei; i++) { + for (int i = 0; i < hei; ++i) { bcalc[i] = new float[wid]; } #ifdef _RT_NESTED_OPENMP - #pragma omp parallel for if(multiThread) + #pragma omp parallel for if (multiThread) #endif - for(int ii = 0; ii < hei; ii++) { - for(int jj = 0; jj < wid; jj++) { + for (int ii = 0; ii < hei; ++ii) { + for (int jj = 0; jj < wid; ++jj) { float LLum, AAum, BBum; float RL = provicalc->r(ii, jj); float GL = provicalc->g(ii, jj); @@ -3246,12 +3215,12 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise_info(Imagefloat * src, Imagefloat int tilesize; int overlap; - if(settings->leveldnti == 0) { + if (settings->leveldnti == 0) { tilesize = 1024; overlap = 128; } - if(settings->leveldnti == 1) { + if (settings->leveldnti == 1) { tilesize = 768; overlap = 96; } @@ -3285,17 +3254,17 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise_info(Imagefloat * src, Imagefloat LUTf *denoiseigamtab; switch(settings->denoiselabgamma) { - case 0: - denoiseigamtab = &(Color::igammatab_26_11); - break; + case 0: + denoiseigamtab = &(Color::igammatab_26_11); + break; - case 1: - denoiseigamtab = &(Color::igammatab_4); - break; + case 1: + denoiseigamtab = &(Color::igammatab_4); + break; - default: - denoiseigamtab = &(Color::igammatab_55); - break; + default: + denoiseigamtab = &(Color::igammatab_55); + break; } @@ -3309,19 +3278,19 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise_info(Imagefloat * src, Imagefloat LabImage * labdn = new LabImage(width, height); float** noisevarlum = new float*[(height + 1) / 2]; - for (int i = 0; i < (height + 1) / 2; i++) { + for (int i = 0; i < (height + 1) / 2; ++i) { noisevarlum[i] = new float[(width + 1) / 2]; } float** noisevarchrom = new float*[(height + 1) / 2]; - for (int i = 0; i < (height + 1) / 2; i++) { + for (int i = 0; i < (height + 1) / 2; ++i) { noisevarchrom[i] = new float[(width + 1) / 2]; } float** noisevarhue = new float*[(height + 1) / 2]; - for (int i = 0; i < (height + 1) / 2; i++) { + for (int i = 0; i < (height + 1) / 2; ++i) { noisevarhue[i] = new float[(width + 1) / 2]; } @@ -3329,19 +3298,19 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise_info(Imagefloat * src, Imagefloat float noisevarab_b, noisevarab_r; float realred, realblue; - float interm_med = (float) dnparams.chroma / 10.0; + float interm_med = static_cast( dnparams.chroma) / 10.0; float intermred, intermblue; - if(dnparams.redchro > 0.) { + if (dnparams.redchro > 0.) { intermred = (dnparams.redchro / 10.); } else { - intermred = (float) dnparams.redchro / 7.0; //increase slower than linear for more sensit + intermred = static_cast( dnparams.redchro) / 7.0; //increase slower than linear for more sensit } - if(dnparams.bluechro > 0.) { + if (dnparams.bluechro > 0.) { intermblue = (dnparams.bluechro / 10.); } else { - intermblue = (float) dnparams.bluechro / 7.0; //increase slower than linear for more sensit + intermblue = static_cast( dnparams.bluechro) / 7.0; //increase slower than linear for more sensit } realred = interm_med + intermred; @@ -3361,7 +3330,7 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise_info(Imagefloat * src, Imagefloat if (isRAW) {//image is raw; use channel differences for chroma channels #ifdef _RT_NESTED_OPENMP - #pragma omp parallel for if(multiThread) + #pragma omp parallel for if (multiThread) #endif for (int i = tiletop; i < tilebottom; i += 2) { @@ -3386,7 +3355,7 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise_info(Imagefloat * src, Imagefloat float cN = sqrtf(SQR(aN) + SQR(bN)); noisevarhue[i1 >> 1][j1 >> 1] = xatan2f(bN, aN); - if(cN < 100.f) { + if (cN < 100.f) { cN = 100.f; //avoid divided by zero } @@ -3402,7 +3371,7 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise_info(Imagefloat * src, Imagefloat float cN = sqrtf(SQR(aN) + SQR(bN)); float hN = xatan2f(bN, aN); - if(cN < 100.f) { + if (cN < 100.f) { cN = 100.f; //avoid divided by zero } @@ -3414,7 +3383,7 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise_info(Imagefloat * src, Imagefloat } #ifdef _RT_NESTED_OPENMP - #pragma omp parallel for if(multiThread) + #pragma omp parallel for if (multiThread) #endif for (int i = tiletop; i < tilebottom; i += 2) { @@ -3432,13 +3401,13 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise_info(Imagefloat * src, Imagefloat if (!denoiseMethodRgb) { //lab mode, modification Jacques feb 2013 and july 2014 #ifdef _RT_NESTED_OPENMP - #pragma omp parallel for if(multiThread) + #pragma omp parallel for if (multiThread) #endif - for (int i = tiletop; i < tilebottom; i++) { + for (int i = tiletop; i < tilebottom; ++i) { int i1 = i - tiletop; - for (int j = tileleft; j < tileright; j++) { + for (int j = tileleft; j < tileright; ++j) { int j1 = j - tileleft; float R_ = gain * src->r(i, j); float G_ = gain * src->g(i, j); @@ -3449,9 +3418,9 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise_info(Imagefloat * src, Imagefloat B_ = (*denoiseigamtab)[B_]; //apply gamma noise standard (slider) - R_ = R_ < 65535.0f ? gamcurve[R_] : (Color::gamman((double)R_ / 65535.0, gam) * 32768.0f); - G_ = G_ < 65535.0f ? gamcurve[G_] : (Color::gamman((double)G_ / 65535.0, gam) * 32768.0f); - B_ = B_ < 65535.0f ? gamcurve[B_] : (Color::gamman((double)B_ / 65535.0, gam) * 32768.0f); + R_ = R_ < 65535.0f ? gamcurve[R_] : (Color::gamman(static_cast(R_) / 65535.0, gam) * 32768.0f); + G_ = G_ < 65535.0f ? gamcurve[G_] : (Color::gamman(static_cast(G_) / 65535.0, gam) * 32768.0f); + B_ = B_ < 65535.0f ? gamcurve[B_] : (Color::gamman(static_cast(B_) / 65535.0, gam) * 32768.0f); //true conversion xyz=>Lab float X, Y, Z; Color::rgbxyz(R_, G_, B_, X, Y, Z, wp); @@ -3466,19 +3435,19 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise_info(Imagefloat * src, Imagefloat } } else { //RGB mode - for (int i = tiletop/*, i1=0*/; i < tilebottom; i++/*, i1++*/) { + for (int i = tiletop/*, i1=0*/; i < tilebottom; ++i/*, ++i1*/) { int i1 = i - tiletop; - for (int j = tileleft/*, j1=0*/; j < tileright; j++/*, j1++*/) { + for (int j = tileleft/*, j1=0*/; j < tileright; ++j/*, ++j1*/) { int j1 = j - tileleft; float X = gain * src->r(i, j); float Y = gain * src->g(i, j); float Z = gain * src->b(i, j); - X = X < 65535.0f ? gamcurve[X] : (Color::gamma((double)X / 65535.0, gam, gamthresh, gamslope, 1.0, 0.0) * 32768.0f); - Y = Y < 65535.0f ? gamcurve[Y] : (Color::gamma((double)Y / 65535.0, gam, gamthresh, gamslope, 1.0, 0.0) * 32768.0f); - Z = Z < 65535.0f ? gamcurve[Z] : (Color::gamma((double)Z / 65535.0, gam, gamthresh, gamslope, 1.0, 0.0) * 32768.0f); + X = X < 65535.0f ? gamcurve[X] : (Color::gamma(static_cast(X) / 65535.0, gam, gamthresh, gamslope, 1.0, 0.0) * 32768.0f); + Y = Y < 65535.0f ? gamcurve[Y] : (Color::gamma(static_cast(Y) / 65535.0, gam, gamthresh, gamslope, 1.0, 0.0) * 32768.0f); + Z = Z < 65535.0f ? gamcurve[Z] : (Color::gamma(static_cast(Z) / 65535.0, gam, gamthresh, gamslope, 1.0, 0.0) * 32768.0f); labdn->a[i1][j1] = (X - Y); labdn->b[i1][j1] = (Y - Z); @@ -3487,10 +3456,10 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise_info(Imagefloat * src, Imagefloat } } else {//image is not raw; use Lab parametrization - for (int i = tiletop/*, i1=0*/; i < tilebottom; i++/*, i1++*/) { + for (int i = tiletop/*, i1=0*/; i < tilebottom; ++i/*, ++i1*/) { int i1 = i - tiletop; - for (int j = tileleft/*, j1=0*/; j < tileright; j++/*, j1++*/) { + for (int j = tileleft/*, j1=0*/; j < tileright; ++j/*, ++j1*/) { int j1 = j - tileleft; float L, a, b; float rLum = src->r(i, j) ; //for luminance denoise curve @@ -3505,9 +3474,9 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise_info(Imagefloat * src, Imagefloat float btmp = Color::igammatab_srgb[ src->b(i, j) ]; //modification Jacques feb 2013 // gamma slider different from raw - rtmp = rtmp < 65535.0f ? gamcurve[rtmp] : (Color::gamman((double)rtmp / 65535.0, gam) * 32768.0f); - gtmp = gtmp < 65535.0f ? gamcurve[gtmp] : (Color::gamman((double)gtmp / 65535.0, gam) * 32768.0f); - btmp = btmp < 65535.0f ? gamcurve[btmp] : (Color::gamman((double)btmp / 65535.0, gam) * 32768.0f); + rtmp = rtmp < 65535.0f ? gamcurve[rtmp] : (Color::gamman(static_cast(rtmp) / 65535.0, gam) * 32768.0f); + gtmp = gtmp < 65535.0f ? gamcurve[gtmp] : (Color::gamman(static_cast(gtmp) / 65535.0, gam) * 32768.0f); + btmp = btmp < 65535.0f ? gamcurve[btmp] : (Color::gamman(static_cast(btmp) / 65535.0, gam) * 32768.0f); float X, Y, Z; Color::rgbxyz(rtmp, gtmp, btmp, X, Y, Z, wp); @@ -3515,18 +3484,18 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise_info(Imagefloat * src, Imagefloat //convert Lab Color::XYZ2Lab(X, Y, Z, L, a, b); - if(((i1 | j1) & 1) == 0) { + if (((i1 | j1) & 1) == 0) { float Llum, alum, blum; float XL, YL, ZL; Color::rgbxyz(rLum, gLum, bLum, XL, YL, ZL, wp); Color::XYZ2Lab(XL, YL, ZL, Llum, alum, blum); float kN = Llum; - if(kN < 2.f) { + if (kN < 2.f) { kN = 2.f; } - if(kN > 32768.f) { + if (kN > 32768.f) { kN = 32768.f; } @@ -3536,7 +3505,7 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise_info(Imagefloat * src, Imagefloat float hN = xatan2f(bN, aN); float cN = sqrt(SQR(aN) + SQR(bN)); - if(cN < 100.f) { + if (cN < 100.f) { cN = 100.f; //avoid divided by zero } @@ -3571,26 +3540,65 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise_info(Imagefloat * src, Imagefloat const int levwav = 5; #ifdef _RT_NESTED_OPENMP - #pragma omp parallel sections if(multiThread) + #pragma omp parallel sections if (multiThread) #endif { #ifdef _RT_NESTED_OPENMP #pragma omp section #endif { - adecomp = new wavelet_decomposition (labdn->data + datalen, labdn->W, labdn->H, levwav, 1 ); + adecomp = new wavelet_decomposition (labdn->data + datalen, labdn->W, labdn->H, levwav, 1); } #ifdef _RT_NESTED_OPENMP #pragma omp section #endif { - bdecomp = new wavelet_decomposition (labdn->data + 2 * datalen, labdn->W, labdn->H, levwav, 1 ); + bdecomp = new wavelet_decomposition (labdn->data + 2 * datalen, labdn->W, labdn->H, levwav, 1); } } bool autoch = dnparams.autochroma; - if(comptlevel == 0) { - WaveletDenoiseAll_info(levwav, *adecomp, *bdecomp, noisevarlum, noisevarchrom, noisevarhue, width, height, noisevarab_r, noisevarab_b, labdn, chaut, Nb, redaut, blueaut, maxredaut, maxblueaut, minredaut, minblueaut, schoice, autoch, chromina, sigma, lumema, sigma_L, redyel, skinc, nsknc, maxchred, maxchblue, minchred, minchblue, nb, chau , chred, chblue, denoiseMethodRgb, multiThread); //enhance mode + if (comptlevel == 0) { + WaveletDenoiseAll_info( + levwav, + *adecomp, + *bdecomp, + noisevarlum, + noisevarchrom, + noisevarhue, + width, + height, + noisevarab_r, + noisevarab_b, + labdn, + chaut, + Nb, + redaut, + blueaut, + maxredaut, + maxblueaut, + minredaut, + minblueaut, + schoice, + autoch, + chromina, + sigma, + lumema, + sigma_L, + redyel, + skinc, + nsknc, + maxchred, + maxchblue, + minchred, + minchblue, + nb, + chau, + chred, + chblue, + denoiseMethodRgb, + multiThread + ); // Enhance mode } comptlevel += 1; @@ -3601,50 +3609,50 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise_info(Imagefloat * src, Imagefloat delete bdecomp; delete labdn; - for (int i = 0; i < (height + 1) / 2; i++) { - delete [] noisevarlum[i]; + for (int i = 0; i < (height + 1) / 2; ++i) { + delete[] noisevarlum[i]; } - delete [] noisevarlum; + delete[] noisevarlum; - for (int i = 0; i < (height + 1) / 2; i++) { - delete [] noisevarchrom[i]; + for (int i = 0; i < (height + 1) / 2; ++i) { + delete[] noisevarchrom[i]; } - delete [] noisevarchrom; + delete[] noisevarchrom; - for (int i = 0; i < (height + 1) / 2; i++) { - delete [] noisevarhue[i]; + for (int i = 0; i < (height + 1) / 2; ++i) { + delete[] noisevarhue[i]; } - delete [] noisevarhue; + delete[] noisevarhue; }//end of tile row }//end of tile loop - for (int i = 0; i < hei; i++) { - delete [] lumcalc[i]; + for (int i = 0; i < hei; ++i) { + delete[] lumcalc[i]; } - delete [] lumcalc; + delete[] lumcalc; - for (int i = 0; i < hei; i++) { - delete [] acalc[i]; + for (int i = 0; i < hei; ++i) { + delete[] acalc[i]; } - delete [] acalc; + delete[] acalc; - for (int i = 0; i < hei; i++) { - delete [] bcalc[i]; + for (int i = 0; i < hei; ++i) { + delete[] bcalc[i]; } - delete [] bcalc; + delete[] bcalc; #undef TS #undef fTS #undef offset #undef epsilon -}//end of main RGB_denoise +} // End of main RGB_denoise } diff --git a/rtengine/PF_correct_RT.cc b/rtengine/PF_correct_RT.cc index fce4a14c0..6864e28ec 100644 --- a/rtengine/PF_correct_RT.cc +++ b/rtengine/PF_correct_RT.cc @@ -31,6 +31,7 @@ #include "../rtgui/myflatcurve.h" #include "rt_math.h" #include "opthelper.h" +#include "median.h" #ifdef _OPENMP #include @@ -766,7 +767,6 @@ SSEFUNCTION void ImProcFunctions::Badpixelscam(CieImage * src, CieImage * dst, d #pragma omp parallel { int ip, in, jp, jn; - float pp[9], temp; #pragma omp for nowait //nowait because next loop inside this parallel region is independent on this one for (int i = 0; i < height; i++) { @@ -795,7 +795,7 @@ SSEFUNCTION void ImProcFunctions::Badpixelscam(CieImage * src, CieImage * dst, d jn = j + 2; } - med3(sraa[ip][jp], sraa[ip][j], sraa[ip][jn], sraa[i][jp], sraa[i][j], sraa[i][jn], sraa[in][jp], sraa[in][j], sraa[in][jn], tmaa[i][j]); + tmaa[i][j] = median(sraa[ip][jp], sraa[ip][j], sraa[ip][jn], sraa[i][jp], sraa[i][j], sraa[i][jn], sraa[in][jp], sraa[in][j], sraa[in][jn]); } } @@ -827,7 +827,7 @@ SSEFUNCTION void ImProcFunctions::Badpixelscam(CieImage * src, CieImage * dst, d jn = j + 2; } - med3(srbb[ip][jp], srbb[ip][j], srbb[ip][jn], srbb[i][jp], srbb[i][j], srbb[i][jn], srbb[in][jp], srbb[in][j], srbb[in][jn], tmbb[i][j]); + tmbb[i][j] = median(srbb[ip][jp], srbb[ip][j], srbb[ip][jn], srbb[i][jp], srbb[i][j], srbb[i][jn], srbb[in][jp], srbb[in][j], srbb[in][jn]); } } } @@ -1374,7 +1374,6 @@ SSEFUNCTION void ImProcFunctions::BadpixelsLab(LabImage * src, LabImage * dst, d #pragma omp parallel { int ip, in, jp, jn; - float pp[9], temp; #pragma omp for nowait //nowait because next loop inside this parallel region is independent on this one for (int i = 0; i < height; i++) { @@ -1403,7 +1402,7 @@ SSEFUNCTION void ImProcFunctions::BadpixelsLab(LabImage * src, LabImage * dst, d jn = j + 2; } - med3(sraa[ip][jp], sraa[ip][j], sraa[ip][jn], sraa[i][jp], sraa[i][j], sraa[i][jn], sraa[in][jp], sraa[in][j], sraa[in][jn], tmaa[i][j]); + tmaa[i][j] = median(sraa[ip][jp], sraa[ip][j], sraa[ip][jn], sraa[i][jp], sraa[i][j], sraa[i][jn], sraa[in][jp], sraa[in][j], sraa[in][jn]); } } @@ -1435,7 +1434,7 @@ SSEFUNCTION void ImProcFunctions::BadpixelsLab(LabImage * src, LabImage * dst, d jn = j + 2; } - med3(srbb[ip][jp], srbb[ip][j], srbb[ip][jn], srbb[i][jp], srbb[i][j], srbb[i][jn], srbb[in][jp], srbb[in][j], srbb[in][jn], tmbb[i][j]); + tmbb[i][j] = median(srbb[ip][jp], srbb[ip][j], srbb[ip][jn], srbb[i][jp], srbb[i][j], srbb[i][jn], srbb[in][jp], srbb[in][j], srbb[in][jn]); } } } diff --git a/rtengine/amaze_demosaic_RT.cc b/rtengine/amaze_demosaic_RT.cc index 6da291303..c5535493c 100644 --- a/rtengine/amaze_demosaic_RT.cc +++ b/rtengine/amaze_demosaic_RT.cc @@ -32,6 +32,7 @@ #include "../rtgui/multilangmgr.h" #include "sleef.c" #include "opthelper.h" +#include "median.h" #include "StopWatch.h" namespace rtengine @@ -552,7 +553,7 @@ SSEFUNCTION void RawImageSource::amaze_demosaic_RT(int winx, int winy, int winw, vfloat hwtv = onev + temp2v / ( epsv + Ginthv + LVF( cfa[indx])); vmask hcdmask = vmaskf_gt( nsgnv * hcdv, ZEROV ); vfloat hcdoldv = hcdv; - vfloat tempv = nsgnv * (LVF(cfa[indx]) - ULIMV( Ginthv, LVFU(cfa[indx - 1]), LVFU(cfa[indx + 1]) )); + vfloat tempv = nsgnv * (LVF(cfa[indx]) - median( Ginthv, LVFU(cfa[indx - 1]), LVFU(cfa[indx + 1]) )); hcdv = vself( vmaskf_lt( temp2v, -(LVF(cfa[indx]) + Ginthv)), tempv, vintpf(hwtv, hcdv, tempv)); hcdv = vself( hcdmask, hcdv, hcdoldv ); hcdv = vself( vmaskf_gt( Ginthv, clip_ptv), tempv, hcdv); @@ -563,7 +564,7 @@ SSEFUNCTION void RawImageSource::amaze_demosaic_RT(int winx, int winy, int winw, vfloat vwtv = onev + temp2v / ( epsv + Gintvv + LVF( cfa[indx])); vmask vcdmask = vmaskf_gt( nsgnv * vcdv, ZEROV ); vfloat vcdoldv = vcdv; - tempv = nsgnv * (LVF(cfa[indx]) - ULIMV( Gintvv, LVF(cfa[indx - v1]), LVF(cfa[indx + v1]) )); + tempv = nsgnv * (LVF(cfa[indx]) - median( Gintvv, LVF(cfa[indx - v1]), LVF(cfa[indx + v1]) )); vcdv = vself( vmaskf_lt( temp2v, -(LVF(cfa[indx]) + Gintvv)), tempv, vintpf(vwtv, vcdv, tempv)); vcdv = vself( vcdmask, vcdv, vcdoldv ); vcdv = vself( vmaskf_gt( Gintvv, clip_ptv), tempv, vcdv); @@ -601,28 +602,28 @@ SSEFUNCTION void RawImageSource::amaze_demosaic_RT(int winx, int winy, int winw, if (hcd[indx] > 0) { if (3.f * hcd[indx] > (Ginth + cfa[indx])) { - hcd[indx] = -ULIM(Ginth, cfa[indx - 1], cfa[indx + 1]) + cfa[indx]; + hcd[indx] = -median(Ginth, cfa[indx - 1], cfa[indx + 1]) + cfa[indx]; } else { float hwt = 1.f - 3.f * hcd[indx] / (eps + Ginth + cfa[indx]); - hcd[indx] = hwt * hcd[indx] + (1.f - hwt) * (-ULIM(Ginth, cfa[indx - 1], cfa[indx + 1]) + cfa[indx]); + hcd[indx] = hwt * hcd[indx] + (1.f - hwt) * (-median(Ginth, cfa[indx - 1], cfa[indx + 1]) + cfa[indx]); } } if (vcd[indx] > 0) { if (3.f * vcd[indx] > (Gintv + cfa[indx])) { - vcd[indx] = -ULIM(Gintv, cfa[indx - v1], cfa[indx + v1]) + cfa[indx]; + vcd[indx] = -median(Gintv, cfa[indx - v1], cfa[indx + v1]) + cfa[indx]; } else { float vwt = 1.f - 3.f * vcd[indx] / (eps + Gintv + cfa[indx]); - vcd[indx] = vwt * vcd[indx] + (1.f - vwt) * (-ULIM(Gintv, cfa[indx - v1], cfa[indx + v1]) + cfa[indx]); + vcd[indx] = vwt * vcd[indx] + (1.f - vwt) * (-median(Gintv, cfa[indx - v1], cfa[indx + v1]) + cfa[indx]); } } if (Ginth > clip_pt) { - hcd[indx] = -ULIM(Ginth, cfa[indx - 1], cfa[indx + 1]) + cfa[indx]; + hcd[indx] = -median(Ginth, cfa[indx - 1], cfa[indx + 1]) + cfa[indx]; } if (Gintv > clip_pt) { - vcd[indx] = -ULIM(Gintv, cfa[indx - v1], cfa[indx + v1]) + cfa[indx]; + vcd[indx] = -median(Gintv, cfa[indx - v1], cfa[indx + v1]) + cfa[indx]; } @@ -633,28 +634,28 @@ SSEFUNCTION void RawImageSource::amaze_demosaic_RT(int winx, int winy, int winw, if (hcd[indx] < 0) { if (3.f * hcd[indx] < -(Ginth + cfa[indx])) { - hcd[indx] = ULIM(Ginth, cfa[indx - 1], cfa[indx + 1]) - cfa[indx]; + hcd[indx] = median(Ginth, cfa[indx - 1], cfa[indx + 1]) - cfa[indx]; } else { float hwt = 1.f + 3.f * hcd[indx] / (eps + Ginth + cfa[indx]); - hcd[indx] = hwt * hcd[indx] + (1.f - hwt) * (ULIM(Ginth, cfa[indx - 1], cfa[indx + 1]) - cfa[indx]); + hcd[indx] = hwt * hcd[indx] + (1.f - hwt) * (median(Ginth, cfa[indx - 1], cfa[indx + 1]) - cfa[indx]); } } if (vcd[indx] < 0) { if (3.f * vcd[indx] < -(Gintv + cfa[indx])) { - vcd[indx] = ULIM(Gintv, cfa[indx - v1], cfa[indx + v1]) - cfa[indx]; + vcd[indx] = median(Gintv, cfa[indx - v1], cfa[indx + v1]) - cfa[indx]; } else { float vwt = 1.f + 3.f * vcd[indx] / (eps + Gintv + cfa[indx]); - vcd[indx] = vwt * vcd[indx] + (1.f - vwt) * (ULIM(Gintv, cfa[indx - v1], cfa[indx + v1]) - cfa[indx]); + vcd[indx] = vwt * vcd[indx] + (1.f - vwt) * (median(Gintv, cfa[indx - v1], cfa[indx + v1]) - cfa[indx]); } } if (Ginth > clip_pt) { - hcd[indx] = ULIM(Ginth, cfa[indx - 1], cfa[indx + 1]) - cfa[indx]; + hcd[indx] = median(Ginth, cfa[indx - 1], cfa[indx + 1]) - cfa[indx]; } if (Gintv > clip_pt) { - vcd[indx] = ULIM(Gintv, cfa[indx - v1], cfa[indx + v1]) - cfa[indx]; + vcd[indx] = median(Gintv, cfa[indx - v1], cfa[indx + v1]) - cfa[indx]; } cddiffsq[indx] = SQR(vcd[indx] - hcd[indx]); @@ -1071,13 +1072,13 @@ SSEFUNCTION void RawImageSource::amaze_demosaic_RT(int winx, int winy, int winw, vfloat rbmv = (wtsev * rbnwv + wtnwv * rbsev) / (wtsev + wtnwv); - temp1v = ULIMV(rbmv , LC2VFU(cfa[indx - m1]), LC2VFU(cfa[indx + m1])); + temp1v = median(rbmv , LC2VFU(cfa[indx - m1]), LC2VFU(cfa[indx + m1])); vfloat wtv = vmul2f(cfav - rbmv) / (epsv + rbmv + cfav); temp2v = vintpf(wtv, rbmv, temp1v); temp2v = vself(vmaskf_lt(rbmv + rbmv, cfav), temp1v, temp2v); temp2v = vself(vmaskf_lt(rbmv, cfav), temp2v, rbmv); - STVFU(rbm[indx1], vself(vmaskf_gt(temp2v, clip_ptv), ULIMV(temp2v , LC2VFU(cfa[indx - m1]), LC2VFU(cfa[indx + m1])), temp2v )); + STVFU(rbm[indx1], vself(vmaskf_gt(temp2v, clip_ptv), median(temp2v , LC2VFU(cfa[indx - m1]), LC2VFU(cfa[indx + m1])), temp2v )); temp1v = LC2VFU(cfa[indx + p1]); @@ -1096,13 +1097,13 @@ SSEFUNCTION void RawImageSource::amaze_demosaic_RT(int winx, int winy, int winw, vfloat rbpv = (wtnev * rbswv + wtswv * rbnev) / (wtnev + wtswv); - temp1v = ULIMV(rbpv , LC2VFU(cfa[indx - p1]), LC2VFU(cfa[indx + p1])); + temp1v = median(rbpv , LC2VFU(cfa[indx - p1]), LC2VFU(cfa[indx + p1])); wtv = vmul2f(cfav - rbpv) / (epsv + rbpv + cfav); temp2v = vintpf(wtv, rbpv, temp1v); temp2v = vself(vmaskf_lt(rbpv + rbpv, cfav), temp1v, temp2v); temp2v = vself(vmaskf_lt(rbpv, cfav), temp2v, rbpv); - STVFU(rbp[indx1], vself(vmaskf_gt(temp2v, clip_ptv), ULIMV(temp2v , LC2VFU(cfa[indx - p1]), LC2VFU(cfa[indx + p1])), temp2v )); + STVFU(rbp[indx1], vself(vmaskf_gt(temp2v, clip_ptv), median(temp2v , LC2VFU(cfa[indx - p1]), LC2VFU(cfa[indx + p1])), temp2v )); vfloat rbvarmv = epssqv + (gausseven0v * (LVFU(Dgrbsq1m[(indx - v1) >> 1]) + LVFU(Dgrbsq1m[(indx - 1) >> 1]) + LVFU(Dgrbsq1m[(indx + 1) >> 1]) + LVFU(Dgrbsq1m[(indx + v1) >> 1])) + gausseven1v * (LVFU(Dgrbsq1m[(indx - v2 - 1) >> 1]) + LVFU(Dgrbsq1m[(indx - v2 + 1) >> 1]) + LVFU(Dgrbsq1m[(indx - 2 - v1) >> 1]) + LVFU(Dgrbsq1m[(indx + 2 - v1) >> 1]) + @@ -1171,28 +1172,28 @@ SSEFUNCTION void RawImageSource::amaze_demosaic_RT(int winx, int winy, int winw, if (rbp[indx1] < cfa[indx]) { if (xmul2f(rbp[indx1]) < cfa[indx]) { - rbp[indx1] = ULIM(rbp[indx1] , cfa[indx - p1], cfa[indx + p1]); + rbp[indx1] = median(rbp[indx1] , cfa[indx - p1], cfa[indx + p1]); } else { float pwt = xmul2f(cfa[indx] - rbp[indx1]) / (eps + rbp[indx1] + cfa[indx]); - rbp[indx1] = pwt * rbp[indx1] + (1.f - pwt) * ULIM(rbp[indx1], cfa[indx - p1], cfa[indx + p1]); + rbp[indx1] = pwt * rbp[indx1] + (1.f - pwt) * median(rbp[indx1], cfa[indx - p1], cfa[indx + p1]); } } if (rbm[indx1] < cfa[indx]) { if (xmul2f(rbm[indx1]) < cfa[indx]) { - rbm[indx1] = ULIM(rbm[indx1] , cfa[indx - m1], cfa[indx + m1]); + rbm[indx1] = median(rbm[indx1] , cfa[indx - m1], cfa[indx + m1]); } else { float mwt = xmul2f(cfa[indx] - rbm[indx1]) / (eps + rbm[indx1] + cfa[indx]); - rbm[indx1] = mwt * rbm[indx1] + (1.f - mwt) * ULIM(rbm[indx1], cfa[indx - m1], cfa[indx + m1]); + rbm[indx1] = mwt * rbm[indx1] + (1.f - mwt) * median(rbm[indx1], cfa[indx - m1], cfa[indx + m1]); } } if (rbp[indx1] > clip_pt) { - rbp[indx1] = ULIM(rbp[indx1], cfa[indx - p1], cfa[indx + p1]); + rbp[indx1] = median(rbp[indx1], cfa[indx - p1], cfa[indx + p1]); } if (rbm[indx1] > clip_pt) { - rbm[indx1] = ULIM(rbm[indx1], cfa[indx - m1], cfa[indx + m1]); + rbm[indx1] = median(rbm[indx1], cfa[indx - m1], cfa[indx + m1]); } } @@ -1254,12 +1255,12 @@ SSEFUNCTION void RawImageSource::amaze_demosaic_RT(int winx, int winy, int winw, gdv = vself(vmaskf_lt(vabsf(onev - crdv), arthreshv), gdv, gd2v); vfloat Gintvv = (LC2VFU(dirwts0[indx - v1]) * gdv + LC2VFU(dirwts0[indx + v1]) * guv) / (LC2VFU(dirwts0[indx + v1]) + LC2VFU(dirwts0[indx - v1])); - vfloat Gint1v = ULIMV(Gintvv , LC2VFU(cfa[indx - v1]), LC2VFU(cfa[indx + v1])); + vfloat Gint1v = median(Gintvv , LC2VFU(cfa[indx - v1]), LC2VFU(cfa[indx + v1])); vfloat vwtv = vmul2f(rbintv - Gintvv) / (epsv + Gintvv + rbintv); vfloat Gint2v = vintpf(vwtv, Gintvv, Gint1v); Gint1v = vself(vmaskf_lt(vmul2f(Gintvv), rbintv), Gint1v, Gint2v); Gintvv = vself(vmaskf_lt(Gintvv, rbintv), Gint1v, Gintvv); - Gintvv = vself(vmaskf_gt(Gintvv, clip_ptv), ULIMV(Gintvv, LC2VFU(cfa[indx - v1]), LC2VFU(cfa[indx + v1])), Gintvv); + Gintvv = vself(vmaskf_gt(Gintvv, clip_ptv), median(Gintvv, LC2VFU(cfa[indx - v1]), LC2VFU(cfa[indx + v1])), Gintvv); vfloat crlv = vmul2f(LC2VFU(cfa[indx - 1])) / (epsv + rbintv + LVFU(rbint[(indx1 - 1)])); vfloat glv = rbintv * crlv; @@ -1272,12 +1273,12 @@ SSEFUNCTION void RawImageSource::amaze_demosaic_RT(int winx, int winy, int winw, grv = vself(vmaskf_lt(vabsf(onev - crrv), arthreshv), grv, gr2v); vfloat Ginthv = (LC2VFU(dirwts1[indx - 1]) * grv + LC2VFU(dirwts1[indx + 1]) * glv) / (LC2VFU(dirwts1[indx - 1]) + LC2VFU(dirwts1[indx + 1])); - vfloat Gint1h = ULIMV(Ginthv , LC2VFU(cfa[indx - 1]), LC2VFU(cfa[indx + 1])); + vfloat Gint1h = median(Ginthv , LC2VFU(cfa[indx - 1]), LC2VFU(cfa[indx + 1])); vfloat hwtv = vmul2f(rbintv - Ginthv) / (epsv + Ginthv + rbintv); vfloat Gint2h = vintpf(hwtv, Ginthv, Gint1h); Gint1h = vself(vmaskf_lt(vmul2f(Ginthv), rbintv), Gint1h, Gint2h); Ginthv = vself(vmaskf_lt(Ginthv, rbintv), Gint1h, Ginthv); - Ginthv = vself(vmaskf_gt(Ginthv, clip_ptv), ULIMV(Ginthv, LC2VFU(cfa[indx - 1]), LC2VFU(cfa[indx + 1])), Ginthv); + Ginthv = vself(vmaskf_gt(Ginthv, clip_ptv), median(Ginthv, LC2VFU(cfa[indx - 1]), LC2VFU(cfa[indx + 1])), Ginthv); vfloat greenv = vself(copymask, vintpf(LVFU(hvwt[indx1]), Gintvv, Ginthv), LC2VFU(rgbgreen[indx])); STC2VFU(rgbgreen[indx], greenv); @@ -1338,28 +1339,28 @@ SSEFUNCTION void RawImageSource::amaze_demosaic_RT(int winx, int winy, int winw, //bound the interpolation in regions of high saturation if (Gintv < rbint[indx1]) { if (2 * Gintv < rbint[indx1]) { - Gintv = ULIM(Gintv , cfa[indx - v1], cfa[indx + v1]); + Gintv = median(Gintv , cfa[indx - v1], cfa[indx + v1]); } else { float vwt = 2.0 * (rbint[indx1] - Gintv) / (eps + Gintv + rbint[indx1]); - Gintv = vwt * Gintv + (1.f - vwt) * ULIM(Gintv, cfa[indx - v1], cfa[indx + v1]); + Gintv = vwt * Gintv + (1.f - vwt) * median(Gintv, cfa[indx - v1], cfa[indx + v1]); } } if (Ginth < rbint[indx1]) { if (2 * Ginth < rbint[indx1]) { - Ginth = ULIM(Ginth , cfa[indx - 1], cfa[indx + 1]); + Ginth = median(Ginth , cfa[indx - 1], cfa[indx + 1]); } else { float hwt = 2.0 * (rbint[indx1] - Ginth) / (eps + Ginth + rbint[indx1]); - Ginth = hwt * Ginth + (1.f - hwt) * ULIM(Ginth, cfa[indx - 1], cfa[indx + 1]); + Ginth = hwt * Ginth + (1.f - hwt) * median(Ginth, cfa[indx - 1], cfa[indx + 1]); } } if (Ginth > clip_pt) { - Ginth = ULIM(Ginth, cfa[indx - 1], cfa[indx + 1]); + Ginth = median(Ginth, cfa[indx - 1], cfa[indx + 1]); } if (Gintv > clip_pt) { - Gintv = ULIM(Gintv, cfa[indx - v1], cfa[indx + v1]); + Gintv = median(Gintv, cfa[indx - v1], cfa[indx + v1]); } rgbgreen[indx] = Ginth * (1.f - hvwt[indx1]) + Gintv * hvwt[indx1]; diff --git a/rtengine/colorclip.h b/rtengine/colorclip.h deleted file mode 100644 index 6a3144166..000000000 --- a/rtengine/colorclip.h +++ /dev/null @@ -1,169 +0,0 @@ -/* - * This file is part of RawTherapee. - * - * Copyright (c) 2004-2010 Gabor Horvath - * - * 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 . - */ -inline double tightestroot (double L, double a, double b, double r1, double r2, double r3); - -#ifndef __COLORCLIP__ -#define __COLORCLIP__ - -#include -#include "median.h" - -// gives back the tightest >0 amplification by which color clipping occures - -inline double tightestroot (double L, double a, double b, double r1, double r2, double r3) -{ - - double an = a / 500.0, bn = b / 200.0, p = (L + 16.0) / 116.0; - - double coeff3 = r1 * an * an * an - r3 * bn * bn * bn; - double coeff2 = 3.0 * p * (r1 * an * an + r3 * bn * bn); - double coeff1 = 3.0 * p * p * (r1 * an - r3 * bn); - double coeff0 = p * p * p * (r1 + r2 + r3) - 1.0; - - double a1 = coeff2 / coeff3; - double a2 = coeff1 / coeff3; - double a3 = coeff0 / coeff3; - - double Q = (a1 * a1 - 3.0 * a2) / 9.0; - double R = (2.0 * a1 * a1 * a1 - 9.0 * a1 * a2 + 27.0 * a3) / 54.0; - double Qcubed = Q * Q * Q; - double d = Qcubed - R * R; - -// printf ("input L=%g, a=%g, b=%g\n", L, a, b); -// printf ("c1=%g, c2=%g, c3=%g, c4=%g\n", coeff3, coeff2, coeff1, coeff0); - - - /* Three real roots */ - if (d >= 0) { - double theta = acos(R / sqrt(Qcubed)); - double sqrtQ = sqrt(Q); - double x0 = -2.0 * sqrtQ * cos( theta / 3.0) - a1 / 3.0; - double x1 = -2.0 * sqrtQ * cos((theta + 2.0 * M_PI) / 3.0) - a1 / 3.0; - double x2 = -2.0 * sqrtQ * cos((theta + 4.0 * M_PI) / 3.0) - a1 / 3.0; - -// printf ("3 roots: %g, %g, %g\n", x0, x1, x2); - - SORT3 (x0, x1, x2, a1, a2, a3); - - if (a1 > 0) { - return a1; - } - - if (a2 > 0) { - return a2; - } - - if (a3 > 0) { - return a3; - } - - return -1; - } - - /* One real root */ - else { -// double e = pow(sqrt(-d) + fabs(R), 1.0 / 3.0); - double e = exp (1.0 / 3.0 * log (sqrt(-d) + fabs(R))); - - if (R > 0) { - e = -e; - } - - double x0 = (e + Q / e) - a1 / 3.0; - -// printf ("1 root: %g\n", x0); - - if (x0 < 0) { - return -1; - } else { - return x0; - } - } -} - - -/******************************************************************************* - * FindCubicRoots - * -------------- - * - * Copyright (C) 1997-2001 Ken Turkowski. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * ------------------------------------------------------------------------ - * - * Solve: - * coeff[3] * x^3 + coeff[2] * x^2 + coeff[1] * x + coeff[0] = 0 - * - * returns: - * 3 - 3 real roots - * 1 - 1 real root (2 complex conjugate) - * - *******************************************************************************/ - -/*long -FindCubicRoots(const FLOAT coeff[4], FLOAT x[3]) -{ - FLOAT a1 = coeff[2] / coeff[3]; - FLOAT a2 = coeff[1] / coeff[3]; - FLOAT a3 = coeff[0] / coeff[3]; - - double_t Q = (a1 * a1 - 3 * a2) / 9; - double_t R = (2 * a1 * a1 * a1 - 9 * a1 * a2 + 27 * a3) / 54; - double_t Qcubed = Q * Q * Q; - double_t d = Qcubed - R * R; - - // Three real roots - if (d >= 0) { - double_t theta = acos(R / sqrt(Qcubed)); - double_t sqrtQ = sqrt(Q); - x[0] = -2 * sqrtQ * cos( theta / 3) - a1 / 3; - x[1] = -2 * sqrtQ * cos((theta + 2 * pi) / 3) - a1 / 3; - x[2] = -2 * sqrtQ * cos((theta + 4 * pi) / 3) - a1 / 3; - return (3); - } - - // One real root - else { - double_t e = pow(sqrt(-d) + fabs(R), 1. / 3.); - if (R > 0) - e = -e; - x[0] = (e + Q / e) - a1 / 3.; - return (1); - } -} -*/ -#endif diff --git a/rtengine/dcraw.cc b/rtengine/dcraw.cc index 47bfd40a7..2bcb0175e 100644 --- a/rtengine/dcraw.cc +++ b/rtengine/dcraw.cc @@ -131,7 +131,7 @@ const float d65_white[3] = { 0.950456, 1, 1.088754 }; #define MIN(a,b) rtengine::min(a,static_cast<__typeof__(a)>(b)) #define MAX(a,b) rtengine::max(a,static_cast<__typeof__(a)>(b)) #define LIM(x,min,max) rtengine::LIM(x,static_cast<__typeof__(x)>(min),static_cast<__typeof__(x)>(max)) -#define ULIM(x,y,z) rtengine::ULIM(x,static_cast<__typeof__(x)>(y),static_cast<__typeof__(x)>(z)) +#define ULIM(x,y,z) rtengine::median(x,static_cast<__typeof__(x)>(y),static_cast<__typeof__(x)>(z)) #define CLIP(x) rtengine::CLIP(x) #define SWAP(a,b) { a=a+b; b=a-b; a=a-b; } diff --git a/rtengine/dcraw.patch b/rtengine/dcraw.patch index 5259c6b67..ad2997ae0 100644 --- a/rtengine/dcraw.patch +++ b/rtengine/dcraw.patch @@ -1,5 +1,5 @@ ---- dcraw.c 2016-06-29 12:25:09 +0000 -+++ dcraw.cc 2016-07-06 12:30:27 +0000 +--- dcraw.c 2016-06-04 20:34:18.405932434 +0200 ++++ dcraw.cc 2016-07-09 17:40:46.405632563 +0200 @@ -1,3 +1,16 @@ +/*RT*/#include +/*RT*/#include @@ -153,7 +153,7 @@ +#define MIN(a,b) rtengine::min(a,static_cast<__typeof__(a)>(b)) +#define MAX(a,b) rtengine::max(a,static_cast<__typeof__(a)>(b)) +#define LIM(x,min,max) rtengine::LIM(x,static_cast<__typeof__(x)>(min),static_cast<__typeof__(x)>(max)) -+#define ULIM(x,y,z) rtengine::ULIM(x,static_cast<__typeof__(x)>(y),static_cast<__typeof__(x)>(z)) ++#define ULIM(x,y,z) rtengine::median(x,static_cast<__typeof__(x)>(y),static_cast<__typeof__(x)>(z)) +#define CLIP(x) rtengine::CLIP(x) #define SWAP(a,b) { a=a+b; b=a-b; a=a-b; } diff --git a/rtengine/demosaic_algos.cc b/rtengine/demosaic_algos.cc index 72f801bab..405a34118 100644 --- a/rtengine/demosaic_algos.cc +++ b/rtengine/demosaic_algos.cc @@ -36,6 +36,7 @@ #include "procparams.h" #include "sleef.c" #include "opthelper.h" +#include "median.h" //#define BENCHMARK #include "StopWatch.h" #ifdef _OPENMP @@ -58,9 +59,6 @@ namespace rtengine #define x00625(a) xdivf(a, 4) #define x0125(a) xdivf(a, 3) - -#define PIX_SORT(a,b) { if ((a)>(b)) {temp=(a);(a)=(b);(b)=temp;} } -#define PIX_SORTV(av,bv) tempv = _mm_min_ps(av,bv); bv = _mm_max_ps(av,bv); av = tempv; extern const Settings* settings; //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -929,7 +927,7 @@ void RawImageSource::ppg_demosaic() } d = dir[i = diff[0] > diff[1]]; - pix[0][1] = ULIM(static_cast(guess[i] >> 2), pix[d][1], pix[-d][1]); + pix[0][1] = median(static_cast(guess[i] >> 2), pix[d][1], pix[-d][1]); } if(plistener) { @@ -1253,8 +1251,8 @@ void RawImageSource::jdl_interpolate_omp() // from "Lassus" for (col = 6 + (FC(row, 2) & 1), indx = row * width + col, c = FC(row, col) / 2; col < u - 6; col += 2, indx += 2) { f[0] = 1.f + 78.f * SQR((float)dif[indx][0]) + 69.f * (SQR((float) dif[indx - v][0]) + SQR((float)dif[indx + v][0])) + 51.f * (SQR((float)dif[indx - x][0]) + SQR((float)dif[indx + x][0])) + 21.f * (SQR((float)dif[indx - z][0]) + SQR((float)dif[indx + z][0])) - 6.f * SQR((float)dif[indx - v][0] + dif[indx][0] + dif[indx + v][0]) - 10.f * (SQR((float)dif[indx - x][0] + dif[indx - v][0] + dif[indx][0]) + SQR((float)dif[indx][0] + dif[indx + v][0] + dif[indx + x][0])) - 7.f * (SQR((float)dif[indx - z][0] + dif[indx - x][0] + dif[indx - v][0]) + SQR((float)dif[indx + v][0] + dif[indx + x][0] + dif[indx + z][0])); f[1] = 1.f + 78.f * SQR((float)dif[indx][1]) + 69.f * (SQR((float)dif[indx - 2][1]) + SQR((float)dif[indx + 2][1])) + 51.f * (SQR((float)dif[indx - 4][1]) + SQR((float)dif[indx + 4][1])) + 21.f * (SQR((float)dif[indx - 6][1]) + SQR((float)dif[indx + 6][1])) - 6.f * SQR((float)dif[indx - 2][1] + dif[indx][1] + dif[indx + 2][1]) - 10.f * (SQR((float)dif[indx - 4][1] + dif[indx - 2][1] + dif[indx][1]) + SQR((float)dif[indx][1] + dif[indx + 2][1] + dif[indx + 4][1])) - 7.f * (SQR((float)dif[indx - 6][1] + dif[indx - 4][1] + dif[indx - 2][1]) + SQR((float)dif[indx + 2][1] + dif[indx + 4][1] + dif[indx + 6][1])); - g[0] = ULIM(0.725f * dif[indx][0] + 0.1375f * dif[indx - v][0] + 0.1375f * dif[indx + v][0], dif[indx - v][0], dif[indx + v][0]); - g[1] = ULIM(0.725f * dif[indx][1] + 0.1375f * dif[indx - 2][1] + 0.1375f * dif[indx + 2][1], dif[indx - 2][1], dif[indx + 2][1]); + g[0] = median(0.725f * dif[indx][0] + 0.1375f * dif[indx - v][0] + 0.1375f * dif[indx + v][0], static_cast(dif[indx - v][0]), static_cast(dif[indx + v][0])); + g[1] = median(0.725f * dif[indx][1] + 0.1375f * dif[indx - 2][1] + 0.1375f * dif[indx + 2][1], static_cast(dif[indx - 2][1]), static_cast(dif[indx + 2][1])); chr[indx][c] = (f[1] * g[0] + f[0] * g[1]) / (f[0] + f[1]); } @@ -1268,10 +1266,10 @@ void RawImageSource::jdl_interpolate_omp() // from "Lassus" f[1] = 1.f / (float)(1.f + fabs((float)chr[indx - u + 1][c] - chr[indx + u - 1][c]) + fabs((float)chr[indx - u + 1][c] - chr[indx - w + 3][c]) + fabs((float)chr[indx + u - 1][c] - chr[indx - w + 3][c])); f[2] = 1.f / (float)(1.f + fabs((float)chr[indx + u - 1][c] - chr[indx - u + 1][c]) + fabs((float)chr[indx + u - 1][c] - chr[indx + w + 3][c]) + fabs((float)chr[indx - u + 1][c] - chr[indx + w - 3][c])); f[3] = 1.f / (float)(1.f + fabs((float)chr[indx + u + 1][c] - chr[indx - u - 1][c]) + fabs((float)chr[indx + u + 1][c] - chr[indx + w - 3][c]) + fabs((float)chr[indx - u - 1][c] - chr[indx + w + 3][c])); - g[0] = ULIM(chr[indx - u - 1][c], chr[indx - w - 1][c], chr[indx - u - 3][c]); - g[1] = ULIM(chr[indx - u + 1][c], chr[indx - w + 1][c], chr[indx - u + 3][c]); - g[2] = ULIM(chr[indx + u - 1][c], chr[indx + w - 1][c], chr[indx + u - 3][c]); - g[3] = ULIM(chr[indx + u + 1][c], chr[indx + w + 1][c], chr[indx + u + 3][c]); + g[0] = median(chr[indx - u - 1][c], chr[indx - w - 1][c], chr[indx - u - 3][c]); + g[1] = median(chr[indx - u + 1][c], chr[indx - w + 1][c], chr[indx - u + 3][c]); + g[2] = median(chr[indx + u - 1][c], chr[indx + w - 1][c], chr[indx + u - 3][c]); + g[3] = median(chr[indx + u + 1][c], chr[indx + w + 1][c], chr[indx + u + 3][c]); chr[indx][c] = (f[0] * g[0] + f[1] * g[1] + f[2] * g[2] + f[3] * g[3]) / (f[0] + f[1] + f[2] + f[3]); image[indx][1] = CLIP(image[indx][2 - d] + chr[indx][1 - c]); image[indx][d] = CLIP(image[indx][1] - chr[indx][c]); @@ -1459,7 +1457,7 @@ SSEFUNCTION void RawImageSource::lmmse_interpolate_omp(int winw, int winh, int i float Y = v0 + xdiv2f(rix[0][0]); if (rix[4][0] > 1.75f * Y) { - rix[0][0] = ULIM(rix[0][0], rix[4][ -1], rix[4][ 1]); + rix[0][0] = median(rix[0][0], rix[4][ -1], rix[4][ 1]); } else { rix[0][0] = LIM(rix[0][0], 0.0f, 1.0f); } @@ -1471,7 +1469,7 @@ SSEFUNCTION void RawImageSource::lmmse_interpolate_omp(int winw, int winh, int i Y = v0 + xdiv2f(rix[1][0]); if (rix[4][0] > 1.75f * Y) { - rix[1][0] = ULIM(rix[1][0], rix[4][-w1], rix[4][w1]); + rix[1][0] = median(rix[1][0], rix[4][-w1], rix[4][w1]); } else { rix[1][0] = LIM(rix[1][0], 0.0f, 1.0f); } @@ -1764,83 +1762,45 @@ SSEFUNCTION void RawImageSource::lmmse_interpolate_omp(int winw, int winh, int i int d = c + 3 - (c == 0 ? 0 : 1); int cc = 1; #ifdef __SSE2__ - __m128 p1v, p2v, p3v, p4v, p5v, p6v, p7v, p8v, p9v, tempv; for (; cc < cc1 - 4; cc += 4) { rix[d] = qix[d] + rr * cc1 + cc; rix[c] = qix[c] + rr * cc1 + cc; rix[1] = qix[1] + rr * cc1 + cc; // Assign 3x3 differential color values - p1v = LVFU(rix[c][-w1 - 1]) - LVFU(rix[1][-w1 - 1]); - p2v = LVFU(rix[c][-w1]) - LVFU(rix[1][-w1]); - p3v = LVFU(rix[c][-w1 + 1]) - LVFU(rix[1][-w1 + 1]); - p4v = LVFU(rix[c][ -1]) - LVFU(rix[1][ -1]); - p5v = LVFU(rix[c][ 0]) - LVFU(rix[1][ 0]); - p6v = LVFU(rix[c][ 1]) - LVFU(rix[1][ 1]); - p7v = LVFU(rix[c][ w1 - 1]) - LVFU(rix[1][ w1 - 1]); - p8v = LVFU(rix[c][ w1]) - LVFU(rix[1][ w1]); - p9v = LVFU(rix[c][ w1 + 1]) - LVFU(rix[1][ w1 + 1]); - // Sort for median of 9 values - PIX_SORTV(p2v, p3v); - PIX_SORTV(p5v, p6v); - PIX_SORTV(p8v, p9v); - PIX_SORTV(p1v, p2v); - PIX_SORTV(p4v, p5v); - PIX_SORTV(p7v, p8v); - PIX_SORTV(p2v, p3v); - PIX_SORTV(p5v, p6v); - PIX_SORTV(p8v, p9v); - p4v = _mm_max_ps(p1v, p4v); - p6v = _mm_min_ps(p6v, p9v); - PIX_SORTV(p5v, p8v); - p7v = _mm_max_ps(p4v, p7v); - p5v = _mm_max_ps(p5v, p2v); - p3v = _mm_min_ps(p3v, p6v); - p5v = _mm_min_ps(p5v, p8v); - PIX_SORTV(p5v, p3v); - p5v = _mm_max_ps(p7v, p5v); - p5v = _mm_min_ps(p3v, p5v); - _mm_storeu_ps(&rix[d][0], p5v); + const std::array p = { + LVFU(rix[c][-w1 - 1]) - LVFU(rix[1][-w1 - 1]), + LVFU(rix[c][-w1]) - LVFU(rix[1][-w1]), + LVFU(rix[c][-w1 + 1]) - LVFU(rix[1][-w1 + 1]), + LVFU(rix[c][ -1]) - LVFU(rix[1][ -1]), + LVFU(rix[c][ 0]) - LVFU(rix[1][ 0]), + LVFU(rix[c][ 1]) - LVFU(rix[1][ 1]), + LVFU(rix[c][ w1 - 1]) - LVFU(rix[1][ w1 - 1]), + LVFU(rix[c][ w1]) - LVFU(rix[1][ w1]), + LVFU(rix[c][ w1 + 1]) - LVFU(rix[1][ w1 + 1]) + }; + _mm_storeu_ps(&rix[d][0], median(p)); } #endif for (; cc < cc1 - 1; cc++) { - float temp; rix[d] = qix[d] + rr * cc1 + cc; rix[c] = qix[c] + rr * cc1 + cc; rix[1] = qix[1] + rr * cc1 + cc; // Assign 3x3 differential color values - float p1 = rix[c][-w1 - 1] - rix[1][-w1 - 1]; - float p2 = rix[c][-w1] - rix[1][-w1]; - float p3 = rix[c][-w1 + 1] - rix[1][-w1 + 1]; - float p4 = rix[c][ -1] - rix[1][ -1]; - float p5 = rix[c][ 0] - rix[1][ 0]; - float p6 = rix[c][ 1] - rix[1][ 1]; - float p7 = rix[c][ w1 - 1] - rix[1][ w1 - 1]; - float p8 = rix[c][ w1] - rix[1][ w1]; - float p9 = rix[c][ w1 + 1] - rix[1][ w1 + 1]; - // Sort for median of 9 values - PIX_SORT(p2, p3); - PIX_SORT(p5, p6); - PIX_SORT(p8, p9); - PIX_SORT(p1, p2); - PIX_SORT(p4, p5); - PIX_SORT(p7, p8); - PIX_SORT(p2, p3); - PIX_SORT(p5, p6); - PIX_SORT(p8, p9); - PIX_SORT(p1, p4); - PIX_SORT(p6, p9); - PIX_SORT(p5, p8); - PIX_SORT(p4, p7); - PIX_SORT(p2, p5); - PIX_SORT(p3, p6); - PIX_SORT(p5, p8); - PIX_SORT(p5, p3); - PIX_SORT(p7, p5); - PIX_SORT(p5, p3); - rix[d][0] = p5; + const std::array p = { + rix[c][-w1 - 1] - rix[1][-w1 - 1], + rix[c][-w1] - rix[1][-w1], + rix[c][-w1 + 1] - rix[1][-w1 + 1], + rix[c][ -1] - rix[1][ -1], + rix[c][ 0] - rix[1][ 0], + rix[c][ 1] - rix[1][ 1], + rix[c][ w1 - 1] - rix[1][ w1 - 1], + rix[c][ w1] - rix[1][ w1], + rix[c][ w1 + 1] - rix[1][ w1 + 1] + }; + rix[d][0] = median(p); } } } @@ -2158,8 +2118,8 @@ SSEFUNCTION void RawImageSource::igv_interpolate(int winw, int winh) egv = LIMV(epssqv + c78v * SQRV(LVFU(hdif[indx1])) + c69v * (SQRV(LVFU(hdif[indx1 - h1])) + SQRV(LVFU(hdif[indx1 + h1]))) + c51v * (SQRV(LVFU(hdif[indx1 - h2])) + SQRV(LVFU(hdif[indx1 + h2]))) + c21v * (SQRV(LVFU(hdif[indx1 - h3])) + SQRV(LVFU(hdif[indx1 + h3]))) - c6v * SQRV(LVFU(hdif[indx1 - h1]) + LVFU(hdif[indx1]) + LVFU(hdif[indx1 + h1])) - c10v * (SQRV(LVFU(hdif[indx1 - h2]) + LVFU(hdif[indx1 - h1]) + LVFU(hdif[indx1])) + SQRV(LVFU(hdif[indx1]) + LVFU(hdif[indx1 + h1]) + LVFU(hdif[indx1 + h2]))) - c7v * (SQRV(LVFU(hdif[indx1 - h3]) + LVFU(hdif[indx1 - h2]) + LVFU(hdif[indx1 - h1])) + SQRV(LVFU(hdif[indx1 + h1]) + LVFU(hdif[indx1 + h2]) + LVFU(hdif[indx1 + h3]))), zerov, onev); //Limit chrominance using H/V neighbourhood - nvv = ULIMV(d725v * LVFU(vdif[indx1]) + d1375v * LVFU(vdif[indx1 - v1]) + d1375v * LVFU(vdif[indx1 + v1]), LVFU(vdif[indx1 - v1]), LVFU(vdif[indx1 + v1])); - evv = ULIMV(d725v * LVFU(hdif[indx1]) + d1375v * LVFU(hdif[indx1 - h1]) + d1375v * LVFU(hdif[indx1 + h1]), LVFU(hdif[indx1 - h1]), LVFU(hdif[indx1 + h1])); + nvv = median(d725v * LVFU(vdif[indx1]) + d1375v * LVFU(vdif[indx1 - v1]) + d1375v * LVFU(vdif[indx1 + v1]), LVFU(vdif[indx1 - v1]), LVFU(vdif[indx1 + v1])); + evv = median(d725v * LVFU(hdif[indx1]) + d1375v * LVFU(hdif[indx1 - h1]) + d1375v * LVFU(hdif[indx1 + h1]), LVFU(hdif[indx1 - h1]), LVFU(hdif[indx1 + h1])); //Chrominance estimation tempv = (egv * nvv + ngv * evv) / (ngv + egv); _mm_storeu_ps(&(chr[d][indx1]), tempv); @@ -2176,8 +2136,8 @@ SSEFUNCTION void RawImageSource::igv_interpolate(int winw, int winh) eg = LIM(epssq + 78.0f * SQR(hdif[indx1]) + 69.0f * (SQR(hdif[indx1 - h1]) + SQR(hdif[indx1 + h1])) + 51.0f * (SQR(hdif[indx1 - h2]) + SQR(hdif[indx1 + h2])) + 21.0f * (SQR(hdif[indx1 - h3]) + SQR(hdif[indx1 + h3])) - 6.0f * SQR(hdif[indx1 - h1] + hdif[indx1] + hdif[indx1 + h1]) - 10.0f * (SQR(hdif[indx1 - h2] + hdif[indx1 - h1] + hdif[indx1]) + SQR(hdif[indx1] + hdif[indx1 + h1] + hdif[indx1 + h2])) - 7.0f * (SQR(hdif[indx1 - h3] + hdif[indx1 - h2] + hdif[indx1 - h1]) + SQR(hdif[indx1 + h1] + hdif[indx1 + h2] + hdif[indx1 + h3])), 0.f, 1.f); //Limit chrominance using H/V neighbourhood - nv = ULIM(0.725f * vdif[indx1] + 0.1375f * vdif[indx1 - v1] + 0.1375f * vdif[indx1 + v1], vdif[indx1 - v1], vdif[indx1 + v1]); - ev = ULIM(0.725f * hdif[indx1] + 0.1375f * hdif[indx1 - h1] + 0.1375f * hdif[indx1 + h1], hdif[indx1 - h1], hdif[indx1 + h1]); + nv = median(0.725f * vdif[indx1] + 0.1375f * vdif[indx1 - v1] + 0.1375f * vdif[indx1 + v1], vdif[indx1 - v1], vdif[indx1 + v1]); + ev = median(0.725f * hdif[indx1] + 0.1375f * hdif[indx1 - h1] + 0.1375f * hdif[indx1 + h1], hdif[indx1 - h1], hdif[indx1 + h1]); //Chrominance estimation chr[d][indx1] = (eg * nv + ng * ev) / (ng + eg); //Green channel population @@ -2207,10 +2167,10 @@ SSEFUNCTION void RawImageSource::igv_interpolate(int winw, int winh) swgv = onev / (epsv + vabsf(LVFU(chr[c][(indx + v1 - h1) >> 1]) - LVFU(chr[c][(indx + v3 + h3) >> 1])) + vabsf(LVFU(chr[c][(indx - v1 + h1) >> 1]) - LVFU(chr[c][(indx + v3 - h3) >> 1]))); segv = onev / (epsv + vabsf(LVFU(chr[c][(indx + v1 + h1) >> 1]) - LVFU(chr[c][(indx + v3 - h3) >> 1])) + vabsf(LVFU(chr[c][(indx - v1 - h1) >> 1]) - LVFU(chr[c][(indx + v3 + h3) >> 1]))); //Limit NW,NE,SW,SE Color differences - nwvv = ULIMV(LVFU(chr[c][(indx - v1 - h1) >> 1]), LVFU(chr[c][(indx - v3 - h1) >> 1]), LVFU(chr[c][(indx - v1 - h3) >> 1])); - nevv = ULIMV(LVFU(chr[c][(indx - v1 + h1) >> 1]), LVFU(chr[c][(indx - v3 + h1) >> 1]), LVFU(chr[c][(indx - v1 + h3) >> 1])); - swvv = ULIMV(LVFU(chr[c][(indx + v1 - h1) >> 1]), LVFU(chr[c][(indx + v3 - h1) >> 1]), LVFU(chr[c][(indx + v1 - h3) >> 1])); - sevv = ULIMV(LVFU(chr[c][(indx + v1 + h1) >> 1]), LVFU(chr[c][(indx + v3 + h1) >> 1]), LVFU(chr[c][(indx + v1 + h3) >> 1])); + nwvv = median(LVFU(chr[c][(indx - v1 - h1) >> 1]), LVFU(chr[c][(indx - v3 - h1) >> 1]), LVFU(chr[c][(indx - v1 - h3) >> 1])); + nevv = median(LVFU(chr[c][(indx - v1 + h1) >> 1]), LVFU(chr[c][(indx - v3 + h1) >> 1]), LVFU(chr[c][(indx - v1 + h3) >> 1])); + swvv = median(LVFU(chr[c][(indx + v1 - h1) >> 1]), LVFU(chr[c][(indx + v3 - h1) >> 1]), LVFU(chr[c][(indx + v1 - h3) >> 1])); + sevv = median(LVFU(chr[c][(indx + v1 + h1) >> 1]), LVFU(chr[c][(indx + v3 + h1) >> 1]), LVFU(chr[c][(indx + v1 + h3) >> 1])); //Interpolate chrominance: R@B and B@R tempv = (nwgv * nwvv + negv * nevv + swgv * swvv + segv * sevv) / (nwgv + negv + swgv + segv); _mm_storeu_ps( &(chr[c][indx >> 1]), tempv); @@ -2223,10 +2183,10 @@ SSEFUNCTION void RawImageSource::igv_interpolate(int winw, int winh) swg = 1.0f / (eps + fabsf(chr[c][(indx + v1 - h1) >> 1] - chr[c][(indx + v3 + h3) >> 1]) + fabsf(chr[c][(indx - v1 + h1) >> 1] - chr[c][(indx + v3 - h3) >> 1])); seg = 1.0f / (eps + fabsf(chr[c][(indx + v1 + h1) >> 1] - chr[c][(indx + v3 - h3) >> 1]) + fabsf(chr[c][(indx - v1 - h1) >> 1] - chr[c][(indx + v3 + h3) >> 1])); //Limit NW,NE,SW,SE Color differences - nwv = ULIM(chr[c][(indx - v1 - h1) >> 1], chr[c][(indx - v3 - h1) >> 1], chr[c][(indx - v1 - h3) >> 1]); - nev = ULIM(chr[c][(indx - v1 + h1) >> 1], chr[c][(indx - v3 + h1) >> 1], chr[c][(indx - v1 + h3) >> 1]); - swv = ULIM(chr[c][(indx + v1 - h1) >> 1], chr[c][(indx + v3 - h1) >> 1], chr[c][(indx + v1 - h3) >> 1]); - sev = ULIM(chr[c][(indx + v1 + h1) >> 1], chr[c][(indx + v3 + h1) >> 1], chr[c][(indx + v1 + h3) >> 1]); + nwv = median(chr[c][(indx - v1 - h1) >> 1], chr[c][(indx - v3 - h1) >> 1], chr[c][(indx - v1 - h3) >> 1]); + nev = median(chr[c][(indx - v1 + h1) >> 1], chr[c][(indx - v3 + h1) >> 1], chr[c][(indx - v1 + h3) >> 1]); + swv = median(chr[c][(indx + v1 - h1) >> 1], chr[c][(indx + v3 - h1) >> 1], chr[c][(indx + v1 - h3) >> 1]); + sev = median(chr[c][(indx + v1 + h1) >> 1], chr[c][(indx + v3 + h1) >> 1], chr[c][(indx + v1 + h3) >> 1]); //Interpolate chrominance: R@B and B@R chr[c][indx >> 1] = (nwg * nwv + neg * nev + swg * swv + seg * sev) / (nwg + neg + swg + seg); } @@ -2487,8 +2447,8 @@ void RawImageSource::igv_interpolate(int winw, int winh) eg = LIM(epssq + 78.0f * SQR(hdif[indx >> 1]) + 69.0f * (SQR(hdif[(indx - h2) >> 1]) + SQR(hdif[(indx + h2) >> 1])) + 51.0f * (SQR(hdif[(indx - h4) >> 1]) + SQR(hdif[(indx + h4) >> 1])) + 21.0f * (SQR(hdif[(indx - h6) >> 1]) + SQR(hdif[(indx + h6) >> 1])) - 6.0f * SQR(hdif[(indx - h2) >> 1] + hdif[indx >> 1] + hdif[(indx + h2) >> 1]) - 10.0f * (SQR(hdif[(indx - h4) >> 1] + hdif[(indx - h2) >> 1] + hdif[indx >> 1]) + SQR(hdif[indx >> 1] + hdif[(indx + h2) >> 1] + hdif[(indx + h4) >> 1])) - 7.0f * (SQR(hdif[(indx - h6) >> 1] + hdif[(indx - h4) >> 1] + hdif[(indx - h2) >> 1]) + SQR(hdif[(indx + h2) >> 1] + hdif[(indx + h4) >> 1] + hdif[(indx + h6) >> 1])), 0.f, 1.f); //Limit chrominance using H/V neighbourhood - nv = ULIM(0.725f * vdif[indx >> 1] + 0.1375f * vdif[(indx - v2) >> 1] + 0.1375f * vdif[(indx + v2) >> 1], vdif[(indx - v2) >> 1], vdif[(indx + v2) >> 1]); - ev = ULIM(0.725f * hdif[indx >> 1] + 0.1375f * hdif[(indx - h2) >> 1] + 0.1375f * hdif[(indx + h2) >> 1], hdif[(indx - h2) >> 1], hdif[(indx + h2) >> 1]); + nv = median(0.725f * vdif[indx >> 1] + 0.1375f * vdif[(indx - v2) >> 1] + 0.1375f * vdif[(indx + v2) >> 1], vdif[(indx - v2) >> 1], vdif[(indx + v2) >> 1]); + ev = median(0.725f * hdif[indx >> 1] + 0.1375f * hdif[(indx - h2) >> 1] + 0.1375f * hdif[(indx + h2) >> 1], hdif[(indx - h2) >> 1], hdif[(indx + h2) >> 1]); //Chrominance estimation chr[d][indx] = (eg * nv + ng * ev) / (ng + eg); //Green channel population @@ -2517,10 +2477,10 @@ void RawImageSource::igv_interpolate(int winw, int winh) swg = 1.0f / (eps + fabsf(chr[c][indx + v1 - h1] - chr[c][indx + v3 + h3]) + fabsf(chr[c][indx - v1 + h1] - chr[c][indx + v3 - h3])); seg = 1.0f / (eps + fabsf(chr[c][indx + v1 + h1] - chr[c][indx + v3 - h3]) + fabsf(chr[c][indx - v1 - h1] - chr[c][indx + v3 + h3])); //Limit NW,NE,SW,SE Color differences - nwv = ULIM(chr[c][indx - v1 - h1], chr[c][indx - v3 - h1], chr[c][indx - v1 - h3]); - nev = ULIM(chr[c][indx - v1 + h1], chr[c][indx - v3 + h1], chr[c][indx - v1 + h3]); - swv = ULIM(chr[c][indx + v1 - h1], chr[c][indx + v3 - h1], chr[c][indx + v1 - h3]); - sev = ULIM(chr[c][indx + v1 + h1], chr[c][indx + v3 + h1], chr[c][indx + v1 + h3]); + nwv = median(chr[c][indx - v1 - h1], chr[c][indx - v3 - h1], chr[c][indx - v1 - h3]); + nev = median(chr[c][indx - v1 + h1], chr[c][indx - v3 + h1], chr[c][indx - v1 + h3]); + swv = median(chr[c][indx + v1 - h1], chr[c][indx + v3 - h1], chr[c][indx + v1 - h3]); + sev = median(chr[c][indx + v1 + h1], chr[c][indx + v3 + h1], chr[c][indx + v1 + h3]); //Interpolate chrominance: R@B and B@R chr[c][indx] = (nwg * nwv + neg * nev + swg * swv + seg * sev) / (nwg + neg + swg + seg); } @@ -2545,10 +2505,10 @@ void RawImageSource::igv_interpolate(int winw, int winh) swg = 1.0f / (eps + fabsf(chr[c][indx + v1 - h1] - chr[c][indx + v3 + h3]) + fabsf(chr[c][indx - v1 + h1] - chr[c][indx + v3 - h3])); seg = 1.0f / (eps + fabsf(chr[c][indx + v1 + h1] - chr[c][indx + v3 - h3]) + fabsf(chr[c][indx - v1 - h1] - chr[c][indx + v3 + h3])); //Limit NW,NE,SW,SE Color differences - nwv = ULIM(chr[c][indx - v1 - h1], chr[c][indx - v3 - h1], chr[c][indx - v1 - h3]); - nev = ULIM(chr[c][indx - v1 + h1], chr[c][indx - v3 + h1], chr[c][indx - v1 + h3]); - swv = ULIM(chr[c][indx + v1 - h1], chr[c][indx + v3 - h1], chr[c][indx + v1 - h3]); - sev = ULIM(chr[c][indx + v1 + h1], chr[c][indx + v3 + h1], chr[c][indx + v1 + h3]); + nwv = median(chr[c][indx - v1 - h1], chr[c][indx - v3 - h1], chr[c][indx - v1 - h3]); + nev = median(chr[c][indx - v1 + h1], chr[c][indx - v3 + h1], chr[c][indx - v1 + h3]); + swv = median(chr[c][indx + v1 - h1], chr[c][indx + v3 - h1], chr[c][indx + v1 - h3]); + sev = median(chr[c][indx + v1 + h1], chr[c][indx + v3 + h1], chr[c][indx + v1 + h3]); //Interpolate chrominance: R@B and B@R chr[c][indx] = (nwg * nwv + neg * nev + swg * swv + seg * sev) / (nwg + neg + swg + seg); } @@ -2730,10 +2690,10 @@ void RawImageSource::ahd_demosaic(int winx, int winy, int winw, int winh) pix = image + (row * width + col); val = 0.25 * ((pix[-1][1] + pix[0][c] + pix[1][1]) * 2 - pix[-2][c] - pix[2][c]) ; - rgb[0][row - top][col - left][1] = ULIM(static_cast(val), pix[-1][1], pix[1][1]); + rgb[0][row - top][col - left][1] = median(static_cast(val), pix[-1][1], pix[1][1]); val = 0.25 * ((pix[-width][1] + pix[0][c] + pix[width][1]) * 2 - pix[-2 * width][c] - pix[2 * width][c]) ; - rgb[1][row - top][col - left][1] = ULIM(static_cast(val), pix[-width][1], pix[width][1]); + rgb[1][row - top][col - left][1] = median(static_cast(val), pix[-width][1], pix[width][1]); } } @@ -3215,39 +3175,21 @@ void RawImageSource::refinement_lassus(int PassCount) g[4] = (f[0] * g[0] + f[1] * g[1] + f[2] * g[2] + f[3] * g[3]) / (f[0] + f[1] + f[2] + f[3]); - float p[9]; - p[0] = (pix[-u - 1][1] - pix[-u - 1][c]); - p[1] = (pix[-u + 0][1] - pix[-u + 0][c]); - p[2] = (pix[-u + 1][1] - pix[-u + 1][c]); - p[3] = (pix[+0 - 1][1] - pix[+0 - 1][c]); - p[4] = (pix[+0 + 0][1] - pix[+0 + 0][c]); - p[5] = (pix[+0 + 1][1] - pix[+0 + 1][c]); - p[6] = (pix[+u - 1][1] - pix[+u - 1][c]); - p[7] = (pix[+u + 0][1] - pix[+u + 0][c]); - p[8] = (pix[+u + 1][1] - pix[+u + 1][c]); + const std::array p = { + pix[-u - 1][1] - pix[-u - 1][c], + pix[-u + 0][1] - pix[-u + 0][c], + pix[-u + 1][1] - pix[-u + 1][c], + pix[+0 - 1][1] - pix[+0 - 1][c], + pix[+0 + 0][1] - pix[+0 + 0][c], + pix[+0 + 1][1] - pix[+0 + 1][c], + pix[+u - 1][1] - pix[+u - 1][c], + pix[+u + 0][1] - pix[+u + 0][c], + pix[+u + 1][1] - pix[+u + 1][c] + }; - // sort p[] - float temp; // used in PIX_SORT macro; - PIX_SORT(p[1], p[2]); - PIX_SORT(p[4], p[5]); - PIX_SORT(p[7], p[8]); - PIX_SORT(p[0], p[1]); - PIX_SORT(p[3], p[4]); - PIX_SORT(p[6], p[7]); - PIX_SORT(p[1], p[2]); - PIX_SORT(p[4], p[5]); - PIX_SORT(p[7], p[8]); - PIX_SORT(p[0], p[3]); - PIX_SORT(p[5], p[8]); - PIX_SORT(p[4], p[7]); - PIX_SORT(p[3], p[6]); - PIX_SORT(p[1], p[4]); - PIX_SORT(p[2], p[5]); - PIX_SORT(p[4], p[7]); - PIX_SORT(p[4], p[2]); - PIX_SORT(p[6], p[4]); - PIX_SORT(p[4], p[2]); - pix[0][c] = LIM(pix[0][1] - (1.30f * g[4] - 0.30f * (pix[0][1] - pix[0][c])), 0.99f * (pix[0][1] - p[4]), 1.01f * (pix[0][1] - p[4])); + const float med = median(p); + + pix[0][c] = LIM(pix[0][1] - (1.30f * g[4] - 0.30f * (pix[0][1] - pix[0][c])), 0.99f * (pix[0][1] - med), 1.01f * (pix[0][1] - med)); } } diff --git a/rtengine/dirpyrLab_denoise.cc b/rtengine/dirpyrLab_denoise.cc deleted file mode 100644 index ee434d75f..000000000 --- a/rtengine/dirpyrLab_denoise.cc +++ /dev/null @@ -1,751 +0,0 @@ -/* - * This file is part of RawTherapee. - * - * 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 . - * - * � 2010 Emil Martinec - * - */ - -#include -#include -#include "curves.h" -#include "labimage.h" -#include "improcfun.h" -#include "array2D.h" -#include "rt_math.h" - -#ifdef _OPENMP -#include -#endif - -#define CLIPC(a) ((a)>-32000?((a)<32000?(a):32000):-32000) - -#define DIRWT_L(i1,j1,i,j) ( rangefn_L[(data_fine->L[i1][j1]-data_fine->L[i][j]+32768)] ) - -#define DIRWT_AB(i1,j1,i,j) ( rangefn_ab[(data_fine->a[i1][j1]-data_fine->a[i][j]+32768)] * \ -rangefn_ab[(data_fine->L[i1][j1]-data_fine->L[i][j]+32768)] * \ -rangefn_ab[(data_fine->b[i1][j1]-data_fine->b[i][j]+32768)] ) - -//#define NRWT_L(a) (nrwt_l[a] ) - -#define NRWT_AB (nrwt_ab[(hipass[1]+32768)] * nrwt_ab[(hipass[2]+32768)]) - - -#define med3(a,b,c) (a(b)) {temp=(a);(a)=(b);(b)=temp;} } - -#define med3x3(a0,a1,a2,a3,a4,a5,a6,a7,a8,median) { \ -p[0]=a0; p[1]=a1; p[2]=a2; p[3]=a3; p[4]=a4; p[5]=a5; p[6]=a6; p[7]=a7; p[8]=a8; \ -PIX_SORT(p[1],p[2]); PIX_SORT(p[4],p[5]); PIX_SORT(p[7],p[8]); \ -PIX_SORT(p[0],p[1]); PIX_SORT(p[3],p[4]); PIX_SORT(p[6],p[7]); \ -PIX_SORT(p[1],p[2]); PIX_SORT(p[4],p[5]); PIX_SORT(p[7],p[8]); \ -PIX_SORT(p[0],p[3]); PIX_SORT(p[5],p[8]); PIX_SORT(p[4],p[7]); \ -PIX_SORT(p[3],p[6]); PIX_SORT(p[1],p[4]); PIX_SORT(p[2],p[5]); \ -PIX_SORT(p[4],p[7]); PIX_SORT(p[4],p[2]); PIX_SORT(p[6],p[4]); \ -PIX_SORT(p[4],p[2]); median=p[4];} //a4 is the median - - -namespace rtengine -{ - -static const int maxlevel = 4; - -//sequence of scales -//static const int scales[8] = {1,2,4,8,16,32,64,128}; -//sequence of pitches -//static const int pitches[8] = {1,1,1,1,1,1,1,1}; - -//sequence of scales -//static const int scales[8] = {1,1,1,1,1,1,1,1}; -//sequence of pitches -//static const int pitches[8] = {2,2,2,2,2,2,2,2}; - -//sequence of scales -//static const int scales[8] = {1,1,2,2,4,4,8,8}; -//sequence of pitches -//static const int pitches[8] = {2,1,2,1,2,1,2,1}; - -//sequence of scales -static const int scales[8] = {1, 1, 2, 4, 8, 16, 32, 64}; -//sequence of pitches -static const int pitches[8] = {2, 1, 1, 1, 1, 1, 1, 1}; - -//pitch is spacing of subsampling -//scale is spacing of directional averaging weights -//example 1: no subsampling at any level -- pitch=1, scale=2^n -//example 2: subsampling by 2 every level -- pitch=2, scale=1 at each level -//example 3: no subsampling at first level, subsampling by 2 thereafter -- -// pitch =1, scale=1 at first level; pitch=2, scale=2 thereafter - - - - -void ImProcFunctions :: dirpyrLab_denoise(LabImage * src, LabImage * dst, const procparams::DirPyrDenoiseParams & dnparams ) -{ - float gam = dnparams.gamma / 3.0; - //float gam = 2.0;//min(3.0, 0.1*fabs(c[4])/3.0+0.001); - float gamthresh = 0.03; - float gamslope = exp(log((double)gamthresh) / gam) / gamthresh; - - LUTf gamcurve(65536, 0); - - //DiagonalCurve* lumacurve = new DiagonalCurve (dnparams.lumcurve, CURVES_MIN_POLY_POINTS); - //DiagonalCurve* chromacurve = new DiagonalCurve (dnparams.chromcurve, CURVES_MIN_POLY_POINTS); - //LUTf Lcurve(65536); - //LUTf abcurve(65536); - for (int i = 0; i < 65536; i++) { - int g = (int)(CurveFactory::gamma((double)i / 65535.0, gam, gamthresh, gamslope, 1.0, 0.0) * 65535.0); - gamcurve[i] = CLIP(g); - /*float val = (float)i/65535.0; - float Lval = (2*(lumacurve->getVal(val))); - float abval = (2*(chromacurve->getVal(val))); - - Lcurve[i] = SQR(Lval); - abcurve[i] = SQR(abval); - if (i % 1000 ==0) printf("%d Lmult=%f abmult=%f \n",i,Lcurve[i],abcurve[i]);*/ - } - - //delete lumacurve; - //delete chromacurve; - - - - //#pragma omp parallel for if (multiThread) - for (int i = 0; i < src->H; i++) { - for (int j = 0; j < src->W; j++) { - //src->L[i][j] = CurveFactory::flinterp(gamcurve,src->L[i][j]); - src->L[i][j] = gamcurve[src->L[i][j]]; - } - } - - //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - - - - LUTf rangefn_L(65536); - LUTf nrwt_l(65536); - - LUTf rangefn_ab(65536); - LUTf nrwt_ab(65536); - - //set up NR weight functions - - //gamma correction for chroma in shadows - float nrwtl_norm = ((CurveFactory::gamma((double)65535.0 / 65535.0, gam, gamthresh, gamslope, 1.0, 0.0)) - - (CurveFactory::gamma((double)75535.0 / 65535.0, gam, gamthresh, gamslope, 1.0, 0.0))); - - for (int i = 0; i < 65536; i++) { - nrwt_l[i] = ((CurveFactory::gamma((double)i / 65535.0, gam, gamthresh, gamslope, 1.0, 0.0) - - CurveFactory::gamma((double)(i + 10000) / 65535.0, gam, gamthresh, gamslope, 1.0, 0.0)) ) / nrwtl_norm; - //if (i % 100 ==0) printf("%d %f \n",i,nrwt_l[i]); - } - - float tonefactor = nrwt_l[32768]; - - float noise_L = 10.0 * dnparams.luma; - float noisevar_L = SQR(noise_L); - - float noise_ab = 100.0 * dnparams.chroma; - float noisevar_ab = SQR(noise_ab); - - - //set up range functions - for (int i = 0; i < 65536; i++) { - rangefn_L[i] = (( exp(-(double)fabs(i - 32768) * tonefactor / (1.0 + noise_L)) * (1.0 + noisevar_L) / ((double)(i - 32768) * (double)(i - 32768) + noisevar_L + 1.0))); - } - - for (int i = 0; i < 65536; i++) { - rangefn_ab[i] = (( exp(-(double)fabs(i - 32768) * tonefactor / (1.0 + 3 * noise_ab)) * (1.0 + noisevar_ab) / ((double)(i - 32768) * (double)(i - 32768) + noisevar_ab + 1.0))); - } - - - for (int i = 0; i < 65536; i++) { - nrwt_ab[i] = ((1.0 + abs(i - 32768) / (1.0 + 8 * noise_ab)) * exp(-(double)fabs(i - 32768) / (1.0 + 8 * noise_ab) ) ); - } - - - //for (int i=0; i<65536; i+=100) printf("%d %d \n",i,gamcurve[i]); - - - //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - - - - int level; - - LabImage * dirpyrLablo[maxlevel]; - int w = (int)((src->W - 1) / pitches[0]) + 1; - int h = (int)((src->H - 1) / pitches[0]) + 1; - dirpyrLablo[0] = new LabImage(w, h); - - for (level = 1; level < maxlevel; level++) { - w = (int)((w - 1) / pitches[level]) + 1; - h = (int)((h - 1) / pitches[level]) + 1; - dirpyrLablo[level] = new LabImage(w, h); - }; - - - ////////////////////////////////////////////////////////////////////////////// - - - // c[0] = luma = noise_L - // c[1] = chroma = noise_ab - // c[2] decrease of noise var with scale - // c[3] radius of domain blur at each level - // c[4] shadow smoothing - // c[5] edge preservation - - level = 0; - - int scale = scales[level]; - - int pitch = pitches[level]; - - //int thresh = 10 * c[8]; - //impulse_nr (src, src, m_w1, m_h1, thresh, noisevar); - - dirpyr(src, dirpyrLablo[0], 0, rangefn_L, rangefn_ab, pitch, scale, dnparams.luma, dnparams.chroma ); - - level = 1; - - while(level < maxlevel) { - scale = scales[level]; - pitch = pitches[level]; - - dirpyr(dirpyrLablo[level - 1], dirpyrLablo[level], level, rangefn_L, rangefn_ab, pitch, scale, dnparams.luma, dnparams.chroma ); - - level ++; - } - - - //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - - - - for(int level = maxlevel - 1; level > 0; level--) { - - int scale = scales[level]; - int pitch = pitches[level]; - idirpyr(dirpyrLablo[level], dirpyrLablo[level - 1], level, rangefn_L, nrwt_l, nrwt_ab, pitch, scale, dnparams.luma, dnparams.chroma/*, Lcurve, abcurve*/ ); - } - - - scale = scales[0]; - pitch = pitches[0]; - - // freeing as much memory as possible since the next call to idirpyr will need lots - for(int i = 1; i < maxlevel; i++) { - delete dirpyrLablo[i]; - } - - idirpyr(dirpyrLablo[0], dst, 0, rangefn_L, nrwt_l, nrwt_ab, pitch, scale, dnparams.luma, dnparams.chroma/*, Lcurve, abcurve*/ ); - - // freeing the last bunch of memory - delete dirpyrLablo[0]; - - //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - - - float igam = 1 / gam; - float igamthresh = gamthresh * gamslope; - float igamslope = 1 / gamslope; - - for (int i = 0; i < 65536; i++) { - gamcurve[i] = (CurveFactory::gamma((float)i / 65535.0, igam, igamthresh, igamslope, 1.0, 0.0) * 65535.0); - } - - - if (dnparams.luma > 0) { - for (int i = 0; i < dst->H; i++) - for (int j = 0; j < dst->W; j++) { - dst->L[i][j] = gamcurve[dst->L[i][j]]; - } - } else { - for (int i = 0; i < dst->H; i++) - for (int j = 0; j < dst->W; j++) { - dst->L[i][j] = gamcurve[src->L[i][j]]; - } - } - -} - -void ImProcFunctions::dirpyr(LabImage* data_fine, LabImage* data_coarse, int level, - LUTf & rangefn_L, LUTf & rangefn_ab, int pitch, int scale, - const int luma, const int chroma ) -{ - - //pitch is spacing of subsampling - //scale is spacing of directional averaging weights - //example 1: no subsampling at any level -- pitch=1, scale=2^n - //example 2: subsampling by 2 every level -- pitch=2, scale=1 at each level - //example 3: no subsampling at first level, subsampling by 2 thereafter -- - // pitch =1, scale=1 at first level; pitch=2, scale=2 thereafter - - - //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - // calculate weights, compute directionally weighted average - - int width = data_fine->W; - int height = data_fine->H; - - //generate domain kernel - int halfwin = 3;//min(ceil(2*sig),3); - int scalewin = halfwin * scale; - -#ifdef _OPENMP - #pragma omp parallel for -#endif - - for(int i = 0; i < height; i += pitch ) { - int i1 = i / pitch; - - for(int j = 0, j1 = 0; j < width; j += pitch, j1++) { - float dirwt_l, dirwt_ab, norm_l, norm_ab; - //float lops,aops,bops; - float Lout, aout, bout; - norm_l = norm_ab = 0;//if we do want to include the input pixel in the sum - Lout = 0; - aout = 0; - bout = 0; - - for(int inbr = (i - scalewin); inbr <= (i + scalewin); inbr += scale) { - if (inbr < 0 || inbr > height - 1) { - continue; - } - - for (int jnbr = (j - scalewin); jnbr <= (j + scalewin); jnbr += scale) { - if (jnbr < 0 || jnbr > width - 1) { - continue; - } - - dirwt_l = DIRWT_L(inbr, jnbr, i, j); - dirwt_ab = DIRWT_AB(inbr, jnbr, i, j); - Lout += dirwt_l * data_fine->L[inbr][jnbr]; - aout += dirwt_ab * data_fine->a[inbr][jnbr]; - bout += dirwt_ab * data_fine->b[inbr][jnbr]; - norm_l += dirwt_l; - norm_ab += dirwt_ab; - } - } - - //lops = Lout/norm;//diagnostic - //aops = aout/normab;//diagnostic - //bops = bout/normab;//diagnostic - - data_coarse->L[i1][j1] = Lout / norm_l; //low pass filter - data_coarse->a[i1][j1] = aout / norm_ab; - data_coarse->b[i1][j1] = bout / norm_ab; - - - /*if (level<2 && i>0 && i0 && jL[i-1][j-1], data_fine->L[i-1][j], data_fine->L[i-1][j+1], \ - data_fine->L[i][j-1], data_fine->L[i][j], data_fine->L[i][j+1], \ - data_fine->L[i+1][j-1], data_fine->L[i+1][j], data_fine->L[i+1][j+1]); - //med3x3(data_fine->L[i-1][j-1], data_fine->L[i-1][j], data_fine->L[i-1][j+1], \ - data_fine->L[i][j-1], data_fine->L[i][j], data_fine->L[i][j+1], \ - data_fine->L[i+1][j-1], data_fine->L[i+1][j], data_fine->L[i+1][j+1],Lmed); - - data_coarse->L[i1][j1] = Lhmf; - }*/ - } - } - - - - -} - -//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -void ImProcFunctions::idirpyr(LabImage* data_coarse, LabImage* data_fine, int level, LUTf &rangefn_L, LUTf & nrwt_l, LUTf & nrwt_ab, - int pitch, int scale, const int luma, const int chroma/*, LUTf & Lcurve, LUTf & abcurve*/ ) -{ - - int width = data_fine->W; - int height = data_fine->H; - - array2D nrfactorL (width, height); - - //float eps = 0.0; - - // c[0] noise_L - // c[1] noise_ab (relative to noise_L) - // c[2] decrease of noise var with scale - // c[3] radius of domain blur at each level - // c[4] shadow smoothing - - float noisevar_L = 4 * SQR(25.0 * luma); - float noisevar_ab = 2 * SQR(100.0 * chroma); - float scalefactor = 1.0 / pow(2.0, (level + 1) * 2); //change the last 2 to 1 for longer tail of higher scale NR - - noisevar_L *= scalefactor; - - // for coarsest level, take non-subsampled lopass image and subtract from lopass_fine to generate hipass image - - // denoise hipass image, add back into lopass_fine to generate denoised image at fine scale - - // now iterate: - // (1) take denoised image at level n, expand and smooth using gradient weights from lopass image at level n-1 - // the result is the smoothed image at level n-1 - // (2) subtract smoothed image at level n-1 from lopass image at level n-1 to make hipass image at level n-1 - // (3) denoise the hipass image at level n-1 - // (4) add the denoised image at level n-1 to the smoothed image at level n-1 to make the denoised image at level n-1 - - // note that the coarsest level amounts to skipping step (1) and doing (2,3,4). - // in other words, skip step one if pitch=1 - - // step (1) - - if (pitch == 1) { - - // step (1-2-3-4) - -#ifdef _OPENMP - #pragma omp parallel -#endif - { - -#ifdef _OPENMP - #pragma omp for -#endif - - for(int i = 0; i < height; i++) - for(int j = 0; j < width; j++) - { - float hipass[3], hpffluct[3], tonefactor, nrfactor; - - tonefactor = (nrwt_l[data_coarse->L[i][j]]); - - hipass[1] = data_fine->a[i][j] - data_coarse->a[i][j]; - hipass[2] = data_fine->b[i][j] - data_coarse->b[i][j]; - - //Wiener filter - //luma - if (level < 2) { - hipass[0] = data_fine->L[i][j] - data_coarse->L[i][j]; - hpffluct[0] = SQR(hipass[0]) + SQR(hipass[1]) + SQR(hipass[2]) + 0.001; - nrfactorL[i][j] = (1.0 + hpffluct[0]) / (1.0 + hpffluct[0] + noisevar_L /* * Lcurve[data_coarse->L[i][j]]*/); - //hipass[0] *= hpffluct[0]/(hpffluct[0]+noisevar_L); - //data_fine->L[i][j] = CLIP(hipass[0]+data_coarse->L[i][j]); - } - - //chroma - //hipass[1] = data_fine->a[i][j]-data_coarse->a[i][j]; - //hipass[2] = data_fine->b[i][j]-data_coarse->b[i][j]; - hpffluct[1] = SQR(hipass[1] * tonefactor) + 0.001; - hpffluct[2] = SQR(hipass[2] * tonefactor) + 0.001; - nrfactor = (hpffluct[1] + hpffluct[2]) / ((hpffluct[1] + hpffluct[2]) + noisevar_ab * NRWT_AB); - - hipass[1] *= nrfactor; - hipass[2] *= nrfactor; - - data_fine->a[i][j] = hipass[1] + data_coarse->a[i][j]; - data_fine->b[i][j] = hipass[2] + data_coarse->b[i][j]; - } - - if (level < 2) - { -#ifdef _OPENMP - #pragma omp for -#endif - - for(int i = 0; i < height; i++) - for(int j = 0; j < width; j++) { - - float dirwt_l, norm_l; - float nrfctrave = 0; - norm_l = 0;//if we do want to include the input pixel in the sum - - for(int inbr = max(0, i - 1); inbr <= min(height - 1, i + 1); inbr++) { - for (int jnbr = max(0, j - 1); jnbr <= min(width - 1, j + 1); jnbr++) { - dirwt_l = DIRWT_L(inbr, jnbr, i, j); - nrfctrave += dirwt_l * nrfactorL[inbr][jnbr]; - norm_l += dirwt_l; - } - } - - nrfctrave /= norm_l; - //nrfctrave = nrfactorL[i][j]; - //nrfctrave=1; - - float hipass[3]; - - //luma - - /*if (i>0 && i0 && jL[i][j] - data_coarse->L[i][j]); - //hipass[0] = median*(data_fine->L[i][j]-data_coarse->L[i][j]); - //hipass[0] = nrfactorL[i][j]*(data_fine->L[i][j]-data_coarse->L[i][j]); - data_fine->L[i][j] = CLIP(hipass[0] + data_coarse->L[i][j]); - - //chroma - //hipass[1] = nrfactorab[i][j]*(data_fine->a[i][j]-data_coarse->a[i][j]); - //hipass[2] = nrfactorab[i][j]*(data_fine->b[i][j]-data_coarse->b[i][j]); - - //data_fine->a[i][j] = hipass[1]+data_coarse->a[i][j]; - //data_fine->b[i][j] = hipass[2]+data_coarse->b[i][j]; - } - }//end of luminance correction - - - - }//end of pitch=1 - - } else {//pitch>1 - - LabImage* smooth; - - smooth = new LabImage(width, height); -#ifdef _OPENMP - #pragma omp parallel -#endif - - { - -#ifdef _OPENMP - #pragma omp for -#endif - - for(int i = 0; i < height; i += pitch) { - int ix = i / pitch; - - for(int j = 0, jx = 0; j < width; j += pitch, jx++) { - - //copy common pixels - smooth->L[i][j] = data_coarse->L[ix][jx]; - smooth->a[i][j] = data_coarse->a[ix][jx]; - smooth->b[i][j] = data_coarse->b[ix][jx]; - } - } - - //if (pitch>1) {//pitch=2; step (1) expand coarse image, fill in missing data -#ifdef _OPENMP - #pragma omp for -#endif - - for(int i = 0; i < height - 1; i += 2) - for(int j = 0; j < width - 1; j += 2) { - //do midpoint first - double norm = 0.0, wtdsum[3] = {0.0, 0.0, 0.0}; - - //wtdsum[0]=wtdsum[1]=wtdsum[2]=0.0; - for(int ix = i; ix < min(height, i + 3); ix += 2) - for (int jx = j; jx < min(width, j + 3); jx += 2) { - wtdsum[0] += smooth->L[ix][jx]; - wtdsum[1] += smooth->a[ix][jx]; - wtdsum[2] += smooth->b[ix][jx]; - norm++; - } - - norm = 1 / norm; - smooth->L[i + 1][j + 1] = wtdsum[0] * norm; - smooth->a[i + 1][j + 1] = wtdsum[1] * norm; - smooth->b[i + 1][j + 1] = wtdsum[2] * norm; - } - -#ifdef _OPENMP - #pragma omp for -#endif - - for(int i = 0; i < height - 1; i += 2) - for(int j = 0; j < width - 1; j += 2) { - //now right neighbor - if (j + 1 == width) { - continue; - } - - double norm = 0.0, wtdsum[3] = {0.0, 0.0, 0.0}; - - for (int jx = j; jx < min(width, j + 3); jx += 2) { - wtdsum[0] += smooth->L[i][jx]; - wtdsum[1] += smooth->a[i][jx]; - wtdsum[2] += smooth->b[i][jx]; - norm++; - } - - for (int ix = max(0, i - 1); ix < min(height, i + 2); ix += 2) { - wtdsum[0] += smooth->L[ix][j + 1]; - wtdsum[1] += smooth->a[ix][j + 1]; - wtdsum[2] += smooth->b[ix][j + 1]; - norm++; - } - - norm = 1 / norm; - smooth->L[i][j + 1] = wtdsum[0] * norm; - smooth->a[i][j + 1] = wtdsum[1] * norm; - smooth->b[i][j + 1] = wtdsum[2] * norm; - - //now down neighbor - if (i + 1 == height) { - continue; - } - - norm = 0.0; - wtdsum[0] = wtdsum[1] = wtdsum[2] = 0.0; - - for (int ix = i; ix < min(height, i + 3); ix += 2) { - wtdsum[0] += smooth->L[ix][j]; - wtdsum[1] += smooth->a[ix][j]; - wtdsum[2] += smooth->b[ix][j]; - norm++; - } - - for (int jx = max(0, j - 1); jx < min(width, j + 2); jx += 2) { - wtdsum[0] += smooth->L[i + 1][jx]; - wtdsum[1] += smooth->a[i + 1][jx]; - wtdsum[2] += smooth->b[i + 1][jx]; - norm++; - } - - norm = 1 / norm; - smooth->L[i + 1][j] = wtdsum[0] * norm; - smooth->a[i + 1][j] = wtdsum[1] * norm; - smooth->b[i + 1][j] = wtdsum[2] * norm; - - } - -#ifdef _OPENMP - #pragma omp for -#endif - - // step (2-3-4) - for( int i = 0; i < height; i++) - for(int j = 0; j < width; j++) { - - float tonefactor = (nrwt_l[smooth->L[i][j]]); - //double wtdsum[3], norm; - float hipass[3], hpffluct[3], nrfactor; - - hipass[1] = data_fine->a[i][j] - smooth->a[i][j]; - hipass[2] = data_fine->b[i][j] - smooth->b[i][j]; - - //Wiener filter - //luma - if (level < 2) { - hipass[0] = data_fine->L[i][j] - smooth->L[i][j]; - hpffluct[0] = SQR(hipass[0]) + SQR(hipass[1]) + SQR(hipass[2]) + 0.001; - nrfactorL[i][j] = (1.0 + hpffluct[0]) / (1.0 + hpffluct[0] + noisevar_L /* * Lcurve[smooth->L[i][j]]*/); - //hipass[0] *= hpffluct[0]/(hpffluct[0]+noisevar_L); - //data_fine->L[i][j] = CLIP(hipass[0]+smooth->L[i][j]); - } - - //chroma - //hipass[1] = data_fine->a[i][j]-smooth->a[i][j]; - //hipass[2] = data_fine->b[i][j]-smooth->b[i][j]; - hpffluct[1] = SQR(hipass[1] * tonefactor) + 0.001; - hpffluct[2] = SQR(hipass[2] * tonefactor) + 0.001; - nrfactor = (hpffluct[1] + hpffluct[2]) / ((hpffluct[1] + hpffluct[2]) + noisevar_ab * NRWT_AB /* * abcurve[smooth->L[i][j]]*/); - - hipass[1] *= nrfactor; - hipass[2] *= nrfactor; - - data_fine->a[i][j] = hipass[1] + smooth->a[i][j]; - data_fine->b[i][j] = hipass[2] + smooth->b[i][j]; - } - - - if (level < 2) { -#ifdef _OPENMP - #pragma omp for -#endif - - for(int i = 0; i < height; i++) - for(int j = 0; j < width; j++) { - - float dirwt_l, norm_l; - float nrfctrave = 0; - norm_l = 0;//if we do want to include the input pixel in the sum - - for(int inbr = (i - pitch); inbr <= (i + pitch); inbr += pitch) { - if (inbr < 0 || inbr > height - 1) { - continue; - } - - for (int jnbr = (j - pitch); jnbr <= (j + pitch); jnbr += pitch) { - if (jnbr < 0 || jnbr > width - 1) { - continue; - } - - dirwt_l = DIRWT_L(inbr, jnbr, i, j); - nrfctrave += dirwt_l * nrfactorL[inbr][jnbr]; - norm_l += dirwt_l; - } - } - - nrfctrave /= norm_l; - //nrfctrave = nrfactorL[i][j]; - //nrfctrave=1; - - - float hipass[3]; - - //luma - - /*if (i>0 && i0 && jL[i][j] - smooth->L[i][j]); - //hipass[0] = median*(data_fine->L[i][j]-smooth->L[i][j]); - //hipass[0] = nrfactorL[i][j]*(data_fine->L[i][j]-data_coarse->L[i][j]); - data_fine->L[i][j] = CLIP(hipass[0] + smooth->L[i][j]); - - - //chroma - //hipass[1] = nrfactorab[i][j]*(data_fine->a[i][j]-data_coarse->a[i][j]); - //hipass[2] = nrfactorab[i][j]*(data_fine->b[i][j]-data_coarse->b[i][j]); - - //data_fine->a[i][j] = hipass[1]+data_coarse->a[i][j]; - //data_fine->b[i][j] = hipass[2]+data_coarse->b[i][j]; - } - }//end of luminance correction - - - } // end parallel - delete smooth; - }//end of pitch>1 - -} - - -#undef DIRWT_L -#undef DIRWT_AB - -//#undef NRWT_L -#undef NRWT_AB - -} - diff --git a/rtengine/ffmanager.cc b/rtengine/ffmanager.cc index 6a653eb84..8b26c3121 100644 --- a/rtengine/ffmanager.cc +++ b/rtengine/ffmanager.cc @@ -20,14 +20,7 @@ #include "../rtgui/options.h" #include "rawimage.h" #include "imagedata.h" - -#define PIX_SORT(a,b) { if ((a)>(b)) {temp=(a);(a)=(b);(b)=temp;} } -#define med5(a0,a1,a2,a3,a4,median) { \ -p[0]=a0; p[1]=a1; p[2]=a2; p[3]=a3; p[4]=a4; \ -PIX_SORT(p[0],p[1]) ; PIX_SORT(p[3],p[4]) ; PIX_SORT(p[0],p[3]) ; \ -PIX_SORT(p[1],p[4]) ; PIX_SORT(p[1],p[2]) ; PIX_SORT(p[2],p[3]) ; \ -PIX_SORT(p[1],p[2]) ; median=p[2] ;} - +#include "median.h" namespace rtengine { @@ -217,7 +210,6 @@ void ffInfo::updateRawImage() #endif for (int i = 0; i < H; i++) { - int p[5], temp; int iprev = i < 2 ? i + 2 : i - 2; int inext = i > H - 3 ? i - 2 : i + 2; @@ -225,8 +217,7 @@ void ffInfo::updateRawImage() int jprev = j < 2 ? j + 2 : j - 2; int jnext = j > W - 3 ? j - 2 : j + 2; - med5(ri->data[iprev][j], ri->data[i][jprev], ri->data[i][j], - ri->data[i][jnext], ri->data[inext][j], cfatmp[i * W + j]); + cfatmp[i * W + j] = median(ri->data[iprev][j], ri->data[i][jprev], ri->data[i][j], ri->data[i][jnext], ri->data[inext][j]); } } diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h index ccc77ab9f..3523ee183 100644 --- a/rtengine/improcfun.h +++ b/rtengine/improcfun.h @@ -35,20 +35,6 @@ #include "cplx_wavelet_dec.h" #include "pipettebuffer.h" -#define PIX_SORT(a,b) { if ((a)>(b)) {temp=(a);(a)=(b);(b)=temp;} } - -#define med3(a0,a1,a2,a3,a4,a5,a6,a7,a8,median) { \ -pp[0]=a0; pp[1]=a1; pp[2]=a2; pp[3]=a3; pp[4]=a4; pp[5]=a5; pp[6]=a6; pp[7]=a7; pp[8]=a8; \ -PIX_SORT(pp[1],pp[2]); PIX_SORT(pp[4],pp[5]); PIX_SORT(pp[7],pp[8]); \ -PIX_SORT(pp[0],pp[1]); PIX_SORT(pp[3],pp[4]); PIX_SORT(pp[6],pp[7]); \ -PIX_SORT(pp[1],pp[2]); PIX_SORT(pp[4],pp[5]); PIX_SORT(pp[7],pp[8]); \ -PIX_SORT(pp[0],pp[3]); PIX_SORT(pp[5],pp[8]); PIX_SORT(pp[4],pp[7]); \ -PIX_SORT(pp[3],pp[6]); PIX_SORT(pp[1],pp[4]); PIX_SORT(pp[2],pp[5]); \ -PIX_SORT(pp[4],pp[7]); PIX_SORT(pp[4],pp[2]); PIX_SORT(pp[6],pp[4]); \ -PIX_SORT(pp[4],pp[2]); median=pp[4];} //pp4 = median - - - namespace rtengine { @@ -198,6 +184,14 @@ class ImProcFunctions public: + enum class Median { + TYPE_3X3_SOFT, + TYPE_3X3_STRONG, + TYPE_5X5_SOFT, + TYPE_5X5_STRONG, + TYPE_7X7, + TYPE_9X9 + }; double lumimul[3]; // float chau; @@ -292,7 +286,6 @@ public: // pyramid denoise procparams::DirPyrDenoiseParams dnparams; - void dirpyrLab_denoise(LabImage * src, LabImage * dst, const procparams::DirPyrDenoiseParams & dnparams );//Emil's directional pyramid denoise void dirpyr (LabImage* data_fine, LabImage* data_coarse, int level, LUTf &rangefn_L, LUTf &rangefn_ab, int pitch, int scale, const int luma, int chroma ); void idirpyr (LabImage* data_coarse, LabImage* data_fine, int level, LUTf &rangefn_L, LUTf & nrwt_l, LUTf & nrwt_ab, @@ -325,13 +318,12 @@ public: - enum mediantype {MED_3X3SOFT, MED_3X3STRONG, MED_5X5SOFT, MED_5X5STRONG, MED_7X7, MED_9X9}; - void Median_Denoise( float **src, float **dst, int width, int height, mediantype medianType, int iterations, int numThreads, float **buffer = NULL); - void RGB_denoise(int kall, Imagefloat * src, Imagefloat * dst, Imagefloat * calclum, float * ch_M, float *max_r, float *max_b, bool isRAW, const procparams::DirPyrDenoiseParams & dnparams, const double expcomp, const NoiseCurve & ctNoisCurve , const NoiseCurve & ctNoisCCcurve , float &chaut, float &redaut, float &blueaut, float &maxredaut, float & maxblueaut, float &nresi, float &highresi); + void Median_Denoise( float **src, float **dst, int width, int height, Median medianType, int iterations, int numThreads, float **buffer = NULL); + void RGB_denoise(int kall, Imagefloat * src, Imagefloat * dst, Imagefloat * calclum, float * ch_M, float *max_r, float *max_b, bool isRAW, const procparams::DirPyrDenoiseParams & dnparams, const double expcomp, const NoiseCurve & noiseLCurve , const NoiseCurve & noiseCCurve , float &chaut, float &redaut, float &blueaut, float &maxredaut, float & maxblueaut, float &nresi, float &highresi); void RGB_denoise_infoGamCurve(const procparams::DirPyrDenoiseParams & dnparams, const bool isRAW, LUTf &gamcurve, float &gam, float &gamthresh, float &gamslope); - void RGB_denoise_info(Imagefloat * src, Imagefloat * calclum, bool isRAW, LUTf &gamcurve, float gam, float gamthresh, float gamslope, const procparams::DirPyrDenoiseParams & dnparams, const double expcomp, float &chaut, int &Nb, float &redaut, float &blueaut, float &maxredaut, float & maxblueaut, float &minredaut, float & minblueaut, float &nresi, float &highresi, float &chromina, float &sigma, float &lumema, float &sigma_L, float &redyel, float &skinc, float &nsknc, bool multiThread = false); - void RGBtile_denoise (float * fLblox, int hblproc, float noisevar_L, float * nbrwt, float * blurbuffer ); //for DCT - void RGBoutput_tile_row (float *Lbloxrow, float ** Ldetail, float ** tilemask_out, int height, int width, int top ); + void RGB_denoise_info(Imagefloat * src, Imagefloat * provicalc, bool isRAW, LUTf &gamcurve, float gam, float gamthresh, float gamslope, const procparams::DirPyrDenoiseParams & dnparams, const double expcomp, float &chaut, int &Nb, float &redaut, float &blueaut, float &maxredaut, float & maxblueaut, float &minredaut, float & minblueaut, float &nresi, float &highresi, float &chromina, float &sigma, float &lumema, float &sigma_L, float &redyel, float &skinc, float &nsknc, bool multiThread = false); + void RGBtile_denoise (float * fLblox, int hblproc, float noisevar_Ldetail, float * nbrwt, float * blurbuffer ); //for DCT + void RGBoutput_tile_row (float *bloxrow_L, float ** Ldetail, float ** tilemask_out, int height, int width, int top ); bool WaveletDenoiseAllL(wavelet_decomposition &WaveletCoeffs_L, float *noisevarlum, float madL[8][3], float * vari, int edge); bool WaveletDenoiseAllAB(wavelet_decomposition &WaveletCoeffs_L, wavelet_decomposition &WaveletCoeffs_ab, float *noisevarchrom, float madL[8][3], float noisevar_ab, const bool useNoiseCCurve, bool autoch, bool denoiseMethodRgb); void WaveletDenoiseAll_info(int levwav, wavelet_decomposition &WaveletCoeffs_a, @@ -341,7 +333,7 @@ public: bool WaveletDenoiseAll_BiShrinkL(wavelet_decomposition &WaveletCoeffs_L, float *noisevarlum, float madL[8][3]); bool WaveletDenoiseAll_BiShrinkAB(wavelet_decomposition &WaveletCoeffs_L, wavelet_decomposition &WaveletCoeffs_ab, float *noisevarchrom, float madL[8][3], float noisevar_ab, const bool useNoiseCCurve, bool autoch, bool denoiseMethodRgb); - void ShrinkAllL(wavelet_decomposition &WaveletCoeffs_L, float **buffer, int level, int dir, float *noisevarlum, float * madaL, float * vari, int edge); + void ShrinkAllL(wavelet_decomposition &WaveletCoeffs_L, float **buffer, int level, int dir, float *noisevarlum, float * madL, float * vari, int edge); void ShrinkAllAB(wavelet_decomposition &WaveletCoeffs_L, wavelet_decomposition &WaveletCoeffs_ab, float **buffer, int level, int dir, float *noisevarchrom, float noisevar_ab, const bool useNoiseCCurve, bool autoch, bool denoiseMethodRgb, float * madL, float * madaab = NULL, bool madCalculated = false); void ShrinkAll_info(float ** WavCoeffs_a, float ** WavCoeffs_b, int level, @@ -349,7 +341,7 @@ public: float &maxchred, float &maxchblue, float &minchred, float &minchblue, int &nb, float &chau, float &chred, float &chblue, bool denoiseMethodRgb, bool multiThread); void Noise_residualAB(wavelet_decomposition &WaveletCoeffs_ab, float &chresid, float &chmaxresid, bool denoiseMethodRgb); void calcautodn_info (float &chaut, float &delta, int Nb, int levaut, float maxmax, float lumema, float chromina, int mode, int lissage, float redyel, float skinc, float nsknc); - float MadMax(float * HH_Coeffs, int &max, int datalen); + float MadMax(float * DataList, int &max, int datalen); float Mad(float * DataList, const int datalen); float MadRgb(float * DataList, const int datalen); diff --git a/rtengine/ipretinex.cc b/rtengine/ipretinex.cc index 6773e7a12..06f779875 100644 --- a/rtengine/ipretinex.cc +++ b/rtengine/ipretinex.cc @@ -36,30 +36,20 @@ */ -#include -#include -#include -#include +#include +#include +#include +#include #include "rtengine.h" #include "gauss.h" #include "rawimagesource.h" #include "improcfun.h" #include "opthelper.h" +#include "median.h" #include "StopWatch.h" #define clipretinex( val, minv, maxv ) (( val = (val < minv ? minv : val ) ) > maxv ? maxv : val ) -#define med3(a0,a1,a2,a3,a4,a5,a6,a7,a8,median) { \ -pp[0]=a0; pp[1]=a1; pp[2]=a2; pp[3]=a3; pp[4]=a4; pp[5]=a5; pp[6]=a6; pp[7]=a7; pp[8]=a8; \ -PIX_SORT(pp[1],pp[2]); PIX_SORT(pp[4],pp[5]); PIX_SORT(pp[7],pp[8]); \ -PIX_SORT(pp[0],pp[1]); PIX_SORT(pp[3],pp[4]); PIX_SORT(pp[6],pp[7]); \ -PIX_SORT(pp[1],pp[2]); PIX_SORT(pp[4],pp[5]); PIX_SORT(pp[7],pp[8]); \ -PIX_SORT(pp[0],pp[3]); PIX_SORT(pp[5],pp[8]); PIX_SORT(pp[4],pp[7]); \ -PIX_SORT(pp[3],pp[6]); PIX_SORT(pp[1],pp[4]); PIX_SORT(pp[2],pp[5]); \ -PIX_SORT(pp[4],pp[7]); PIX_SORT(pp[4],pp[2]); PIX_SORT(pp[6],pp[4]); \ -PIX_SORT(pp[4],pp[2]); median=pp[4];} //pp4 = median - - namespace { void retinex_scales( float* scales, int nscales, int mode, int s, float high) @@ -629,10 +619,8 @@ void RawImageSource::MSR(float** luminance, float** originalLuminance, float **e #endif for (int i = borderL; i < hei - borderL; i++) { - float pp[9], temp; - for (int j = borderL; j < wid - borderL; j++) { - med3(luminance[i][j], luminance[i - 1][j], luminance[i + 1][j], luminance[i][j + 1], luminance[i][j - 1], luminance[i - 1][j - 1], luminance[i - 1][j + 1], luminance[i + 1][j - 1], luminance[i + 1][j + 1], tmL[i][j]); //3x3 + tmL[i][j] = median(luminance[i][j], luminance[i - 1][j], luminance[i + 1][j], luminance[i][j + 1], luminance[i][j - 1], luminance[i - 1][j - 1], luminance[i - 1][j + 1], luminance[i + 1][j - 1], luminance[i + 1][j + 1]); //3x3 } } diff --git a/rtengine/ipwavelet.cc b/rtengine/ipwavelet.cc index ab29308c8..0f09f1ddd 100644 --- a/rtengine/ipwavelet.cc +++ b/rtengine/ipwavelet.cc @@ -37,6 +37,7 @@ #include "mytime.h" #include "sleef.c" #include "opthelper.h" +#include "median.h" #include "EdgePreservingDecomposition.h" #ifdef _OPENMP @@ -50,26 +51,6 @@ #define fTS ((TS/2+1)) // second dimension of Fourier tiles #define blkrad 1 // radius of block averaging -#define PIX_SORT(a,b) { if ((a)>(b)) {temp=(a);(a)=(b);(b)=temp;} } - -#define med3(a0,a1,a2,a3,a4,a5,a6,a7,a8,median) { \ -pp[0]=a0; pp[1]=a1; pp[2]=a2; pp[3]=a3; pp[4]=a4; pp[5]=a5; pp[6]=a6; pp[7]=a7; pp[8]=a8; \ -PIX_SORT(pp[1],pp[2]); PIX_SORT(pp[4],pp[5]); PIX_SORT(pp[7],pp[8]); \ -PIX_SORT(pp[0],pp[1]); PIX_SORT(pp[3],pp[4]); PIX_SORT(pp[6],pp[7]); \ -PIX_SORT(pp[1],pp[2]); PIX_SORT(pp[4],pp[5]); PIX_SORT(pp[7],pp[8]); \ -PIX_SORT(pp[0],pp[3]); PIX_SORT(pp[5],pp[8]); PIX_SORT(pp[4],pp[7]); \ -PIX_SORT(pp[3],pp[6]); PIX_SORT(pp[1],pp[4]); PIX_SORT(pp[2],pp[5]); \ -PIX_SORT(pp[4],pp[7]); PIX_SORT(pp[4],pp[2]); PIX_SORT(pp[6],pp[4]); \ -PIX_SORT(pp[4],pp[2]); median=pp[4];} //pp4 = median - - -#define med2(a0,a1,a2,a3,a4,median) { \ -pp[0]=a0; pp[1]=a1; pp[2]=a2; pp[3]=a3; pp[4]=a4; \ -PIX_SORT(pp[0],pp[1]) ; PIX_SORT(pp[3],pp[4]) ; PIX_SORT(pp[0],pp[3]) ;\ -PIX_SORT(pp[1],pp[4]) ; PIX_SORT(pp[1],pp[2]) ; PIX_SORT(pp[2],pp[3]) ;\ -PIX_SORT(pp[1],pp[2]) ; median=pp[2] ;} - - #define epsilon 0.001f/(TS*TS) //tolerance @@ -820,11 +801,9 @@ SSEFUNCTION void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int #endif for (int i = 1; i < hei - 1; i++) { - float pp[9], temp; - for (int j = 1; j < wid - 1; j++) { if((varhue[i][j] < -1.3f && varhue[i][j] > - 2.5f) && (varchro[i][j] > 15.f && varchro[i][j] < 55.f) && labco->L[i][j] > 6000.f) { //blue sky + med3x3 ==> after for more effect use denoise - med3(labco->L[i][j] , labco->L[i - 1][j], labco->L[i + 1][j] , labco->L[i][j + 1], labco->L[i][j - 1], labco->L[i - 1][j - 1], labco->L[i - 1][j + 1], labco->L[i + 1][j - 1], labco->L[i + 1][j + 1], tmL[i][j]); //3x3 + tmL[i][j] = median(labco->L[i][j] , labco->L[i - 1][j], labco->L[i + 1][j] , labco->L[i][j + 1], labco->L[i][j - 1], labco->L[i - 1][j - 1], labco->L[i - 1][j + 1], labco->L[i + 1][j - 1], labco->L[i + 1][j + 1]); //3x3 } } } diff --git a/rtengine/median.h b/rtengine/median.h index d5e88d9de..8c65180ba 100644 --- a/rtengine/median.h +++ b/rtengine/median.h @@ -16,95 +16,6260 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#include "rt_math.h" -// middle 4 of 6 elements, -#define MIDDLE4OF6(s0,s1,s2,s3,s4,s5,d0,d1,d2,d3,d4,d5,temp) \ -{\ -d1 = min(s1,s2);\ -d2 = max(s1,s2);\ -d0 = min(s0,d2);\ -d2 = max(s0,d2);\ -temp = min(d0,d1);\ -d1 = max(d0,d1);\ -d0 = temp;\ -d4 = min(s4,s5);\ -d5 = max(s4,s5);\ -d3 = min(s3,d5);\ -d5 = max(s3,d5);\ -temp = min(d3,d4);\ -d4 = max(d3,d4);\ -d3 = max(d0,temp);\ -d2 = min(d2,d5);\ +#pragma once + +#include +#include + +#include "opthelper.h" + +template +inline T median(std::array array) +{ + const typename std::array::iterator middle = array.begin() + N / 2; + std::nth_element(array.begin(), middle, array.end()); + + return + N % 2 + ? *middle + : ((*middle + *std::max_element(array.begin(), middle)) / static_cast(2)); } -// middle 4 of 6 elements, vectorized -#define VMIDDLE4OF6(s0,s1,s2,s3,s4,s5,d0,d1,d2,d3,d4,d5,temp) \ -{\ -d1 = vminf(s1,s2);\ -d2 = vmaxf(s1,s2);\ -d0 = vminf(s0,d2);\ -d2 = vmaxf(s0,d2);\ -temp = vminf(d0,d1);\ -d1 = vmaxf(d0,d1);\ -d0 = temp;\ -d4 = vminf(s4,s5);\ -d5 = vmaxf(s4,s5);\ -d3 = vminf(s3,d5);\ -d5 = vmaxf(s3,d5);\ -temp = vminf(d3,d4);\ -d4 = vmaxf(d3,d4);\ -d3 = vmaxf(d0,temp);\ -d2 = vminf(d2,d5);\ +template +inline T median(std::array array) +{ + return std::max(std::min(array[0], array[1]), std::min(array[2], std::max(array[0], array[1]))); } +#ifdef __SSE2__ +template<> +inline vfloat median(std::array array) +{ + return vmaxf(vminf(array[0], array[1]), vminf(array[2], vmaxf(array[0], array[1]))); +} +#endif -#define MEDIAN7(s0,s1,s2,s3,s4,s5,s6,t0,t1,t2,t3,t4,t5,t6,median) \ -{\ -t0 = min(s0,s5);\ -t5 = max(s0,s5);\ -t3 = max(t0,s3);\ -t0 = min(t0,s3);\ -t1 = min(s1,s6);\ -t6 = max(s1,s6);\ -t2 = min(s2,s4);\ -t4 = max(s2,s4);\ -t1 = max(t0,t1);\ -median = min(t3,t5);\ -t5 = max(t3,t5);\ -t3 = median;\ -median = min(t2,t6);\ -t6 = max(t2,t6);\ -t3 = max(median,t3);\ -t3 = min(t3,t6);\ -t4 = min(t4,t5);\ -median = min(t1,t4);\ -t4 = max(t1,t4);\ -t3 = max(median,t3);\ -median = min(t3,t4);\ +template +inline T median(std::array array) +{ + T tmp = std::min(array[0], array[1]); + array[1] = std::max(array[0], array[1]); + array[0] = tmp; + tmp = std::min(array[3], array[4]); + array[4] = std::max(array[3], array[4]); + array[3] = std::max(array[0], tmp); + array[1] = std::min(array[1], array[4]); + tmp = std::min(array[1], array[2]); + array[2] = std::max(array[1], array[2]); + array[1] = tmp; + tmp = std::min(array[2], array[3]); + return std::max(array[1], tmp); } -#define VMEDIAN7(s0,s1,s2,s3,s4,s5,s6,t0,t1,t2,t3,t4,t5,t6,median) \ -{\ -t0 = vminf(s0,s5);\ -t5 = vmaxf(s0,s5);\ -t3 = vmaxf(t0,s3);\ -t0 = vminf(t0,s3);\ -t1 = vminf(s1,s6);\ -t6 = vmaxf(s1,s6);\ -t2 = vminf(s2,s4);\ -t4 = vmaxf(s2,s4);\ -t1 = vmaxf(t0,t1);\ -median = vminf(t3,t5);\ -t5 = vmaxf(t3,t5);\ -t3 = median;\ -median = vminf(t2,t6);\ -t6 = vmaxf(t2,t6);\ -t3 = vmaxf(median,t3);\ -t3 = vminf(t3,t6);\ -t4 = vminf(t4,t5);\ -median = vminf(t1,t4);\ -t4 = vmaxf(t1,t4);\ -t3 = vmaxf(median,t3);\ -median = vminf(t3,t4);\ +#ifdef __SSE2__ +template<> +inline vfloat median(std::array array) +{ + vfloat tmp = vminf(array[0], array[1]); + array[1] = vmaxf(array[0], array[1]); + array[0] = tmp; + tmp = vminf(array[3], array[4]); + array[4] = vmaxf(array[3], array[4]); + array[3] = vmaxf(array[0], tmp); + array[1] = vminf(array[1], array[4]); + tmp = vminf(array[1], array[2]); + array[2] = vmaxf(array[1], array[2]); + array[1] = tmp; + tmp = vminf(array[2], array[3]); + return vmaxf(array[1], tmp); +} +#endif + +template +inline T median(std::array array) +{ + T tmp = std::min(array[0], array[5]); + array[5] = std::max(array[0], array[5]); + array[0] = tmp; + tmp = std::min(array[0], array[3]); + array[3] = std::max(array[0], array[3]); + array[0] = tmp; + tmp = std::min(array[1], array[6]); + array[6] = std::max(array[1], array[6]); + array[1] = tmp; + tmp = std::min(array[2], array[4]); + array[4] = std::max(array[2], array[4]); + array[2] = tmp; + array[1] = std::max(array[0], array[1]); + tmp = std::min(array[3], array[5]); + array[5] = std::max(array[3], array[5]); + array[3] = tmp; + tmp = std::min(array[2], array[6]); + array[6] = std::max(array[2], array[6]); + array[3] = std::max(tmp, array[3]); + array[3] = std::min(array[3], array[6]); + tmp = std::min(array[4], array[5]); + array[4] = std::max(array[1], tmp); + tmp = std::min(array[1], tmp); + array[3] = std::max(tmp, array[3]); + return std::min(array[3], array[4]); +} + +#ifdef __SSE2__ +template<> +inline vfloat median(std::array array) +{ + vfloat tmp = vminf(array[0], array[5]); + array[5] = vmaxf(array[0], array[5]); + array[0] = tmp; + tmp = vminf(array[0], array[3]); + array[3] = vmaxf(array[0], array[3]); + array[0] = tmp; + tmp = vminf(array[1], array[6]); + array[6] = vmaxf(array[1], array[6]); + array[1] = tmp; + tmp = vminf(array[2], array[4]); + array[4] = vmaxf(array[2], array[4]); + array[2] = tmp; + array[1] = vmaxf(array[0], array[1]); + tmp = vminf(array[3], array[5]); + array[5] = vmaxf(array[3], array[5]); + array[3] = tmp; + tmp = vminf(array[2], array[6]); + array[6] = vmaxf(array[2], array[6]); + array[3] = vmaxf(tmp, array[3]); + array[3] = vminf(array[3], array[6]); + tmp = vminf(array[4], array[5]); + array[4] = vmaxf(array[1], tmp); + tmp = vminf(array[1], tmp); + array[3] = vmaxf(tmp, array[3]); + return vminf(array[3], array[4]); +} +#endif + +template +inline T median(std::array array) +{ + T tmp = std::min(array[1], array[2]); + array[2] = std::max(array[1], array[2]); + array[1] = tmp; + tmp = std::min(array[4], array[5]); + array[5] = std::max(array[4], array[5]); + array[4] = tmp; + tmp = std::min(array[7], array[8]); + array[8] = std::max(array[7], array[8]); + array[7] = tmp; + tmp = std::min(array[0], array[1]); + array[1] = std::max(array[0], array[1]); + array[0] = tmp; + tmp = std::min(array[3], array[4]); + array[4] = std::max(array[3], array[4]); + array[3] = tmp; + tmp = std::min(array[6], array[7]); + array[7] = std::max(array[6], array[7]); + array[6] = tmp; + tmp = std::min(array[1], array[2]); + array[2] = std::max(array[1], array[2]); + array[1] = tmp; + tmp = std::min(array[4], array[5]); + array[5] = std::max(array[4], array[5]); + array[4] = tmp; + tmp = std::min(array[7], array[8]); + array[8] = std::max(array[7], array[8]); + array[3] = std::max(array[0], array[3]); + array[5] = std::min(array[5], array[8]); + array[7] = std::max(array[4], tmp); + tmp = std::min(array[4], tmp); + array[6] = std::max(array[3], array[6]); + array[4] = std::max(array[1], tmp); + array[2] = std::min(array[2], array[5]); + array[4] = std::min(array[4], array[7]); + tmp = std::min(array[4], array[2]); + array[2] = std::max(array[4], array[2]); + array[4] = std::max(array[6], tmp); + return std::min(array[4], array[2]); +} + +#ifdef __SSE2__ +template<> +inline vfloat median(std::array array) +{ + vfloat tmp = vminf(array[1], array[2]); + array[2] = vmaxf(array[1], array[2]); + array[1] = tmp; + tmp = vminf(array[4], array[5]); + array[5] = vmaxf(array[4], array[5]); + array[4] = tmp; + tmp = vminf(array[7], array[8]); + array[8] = vmaxf(array[7], array[8]); + array[7] = tmp; + tmp = vminf(array[0], array[1]); + array[1] = vmaxf(array[0], array[1]); + array[0] = tmp; + tmp = vminf(array[3], array[4]); + array[4] = vmaxf(array[3], array[4]); + array[3] = tmp; + tmp = vminf(array[6], array[7]); + array[7] = vmaxf(array[6], array[7]); + array[6] = tmp; + tmp = vminf(array[1], array[2]); + array[2] = vmaxf(array[1], array[2]); + array[1] = tmp; + tmp = vminf(array[4], array[5]); + array[5] = vmaxf(array[4], array[5]); + array[4] = tmp; + tmp = vminf(array[7], array[8]); + array[8] = vmaxf(array[7], array[8]); + array[3] = vmaxf(array[0], array[3]); + array[5] = vminf(array[5], array[8]); + array[7] = vmaxf(array[4], tmp); + tmp = vminf(array[4], tmp); + array[6] = vmaxf(array[3], array[6]); + array[4] = vmaxf(array[1], tmp); + array[2] = vminf(array[2], array[5]); + array[4] = vminf(array[4], array[7]); + tmp = vminf(array[4], array[2]); + array[2] = vmaxf(array[4], array[2]); + array[4] = vmaxf(array[6], tmp); + return vminf(array[4], array[2]); +} +#endif + +template +inline T median(std::array array) +{ + T tmp = std::min(array[1], array[7]); + array[7] = std::max(array[1], array[7]); + array[1] = tmp; + tmp = std::min(array[9], array[11]); + array[11] = std::max(array[9], array[11]); + array[9] = tmp; + tmp = std::min(array[3], array[4]); + array[4] = std::max(array[3], array[4]); + array[3] = tmp; + tmp = std::min(array[5], array[8]); + array[8] = std::max(array[5], array[8]); + array[5] = tmp; + tmp = std::min(array[0], array[12]); + array[12] = std::max(array[0], array[12]); + array[0] = tmp; + tmp = std::min(array[2], array[6]); + array[6] = std::max(array[2], array[6]); + array[2] = tmp; + tmp = std::min(array[0], array[1]); + array[1] = std::max(array[0], array[1]); + array[0] = tmp; + tmp = std::min(array[2], array[3]); + array[3] = std::max(array[2], array[3]); + array[2] = tmp; + tmp = std::min(array[4], array[6]); + array[6] = std::max(array[4], array[6]); + array[4] = tmp; + tmp = std::min(array[8], array[11]); + array[11] = std::max(array[8], array[11]); + array[8] = tmp; + tmp = std::min(array[7], array[12]); + array[12] = std::max(array[7], array[12]); + array[7] = tmp; + tmp = std::min(array[5], array[9]); + array[9] = std::max(array[5], array[9]); + array[5] = tmp; + tmp = std::min(array[0], array[2]); + array[2] = std::max(array[0], array[2]); + array[0] = tmp; + tmp = std::min(array[3], array[7]); + array[7] = std::max(array[3], array[7]); + array[3] = tmp; + tmp = std::min(array[10], array[11]); + array[11] = std::max(array[10], array[11]); + array[10] = tmp; + tmp = std::min(array[1], array[4]); + array[4] = std::max(array[1], array[4]); + array[1] = tmp; + tmp = std::min(array[6], array[12]); + array[12] = std::max(array[6], array[12]); + array[6] = tmp; + tmp = std::min(array[7], array[8]); + array[8] = std::max(array[7], array[8]); + array[7] = tmp; + array[11] = std::min(array[11], array[12]); + tmp = std::min(array[4], array[9]); + array[9] = std::max(array[4], array[9]); + array[4] = tmp; + tmp = std::min(array[6], array[10]); + array[10] = std::max(array[6], array[10]); + array[6] = tmp; + tmp = std::min(array[3], array[4]); + array[4] = std::max(array[3], array[4]); + array[3] = tmp; + tmp = std::min(array[5], array[6]); + array[6] = std::max(array[5], array[6]); + array[5] = tmp; + array[8] = std::min(array[8], array[9]); + array[10] = std::min(array[10], array[11]); + tmp = std::min(array[1], array[7]); + array[7] = std::max(array[1], array[7]); + array[1] = tmp; + tmp = std::min(array[2], array[6]); + array[6] = std::max(array[2], array[6]); + array[2] = tmp; + array[3] = std::max(array[1], array[3]); + tmp = std::min(array[4], array[7]); + array[7] = std::max(array[4], array[7]); + array[4] = tmp; + array[8] = std::min(array[8], array[10]); + array[5] = std::max(array[0], array[5]); + array[5] = std::max(array[2], array[5]); + tmp = std::min(array[6], array[8]); + array[8] = std::max(array[6], array[8]); + array[5] = std::max(array[3], array[5]); + array[7] = std::min(array[7], array[8]); + array[6] = std::max(array[4], tmp); + tmp = std::min(array[4], tmp); + array[5] = std::max(tmp, array[5]); + array[6] = std::min(array[6], array[7]); + return std::max(array[5], array[6]); +} + +#ifdef __SSE2__ +template<> +inline vfloat median(std::array array) +{ + vfloat tmp = vminf(array[1], array[7]); + array[7] = vmaxf(array[1], array[7]); + array[1] = tmp; + tmp = vminf(array[9], array[11]); + array[11] = vmaxf(array[9], array[11]); + array[9] = tmp; + tmp = vminf(array[3], array[4]); + array[4] = vmaxf(array[3], array[4]); + array[3] = tmp; + tmp = vminf(array[5], array[8]); + array[8] = vmaxf(array[5], array[8]); + array[5] = tmp; + tmp = vminf(array[0], array[12]); + array[12] = vmaxf(array[0], array[12]); + array[0] = tmp; + tmp = vminf(array[2], array[6]); + array[6] = vmaxf(array[2], array[6]); + array[2] = tmp; + tmp = vminf(array[0], array[1]); + array[1] = vmaxf(array[0], array[1]); + array[0] = tmp; + tmp = vminf(array[2], array[3]); + array[3] = vmaxf(array[2], array[3]); + array[2] = tmp; + tmp = vminf(array[4], array[6]); + array[6] = vmaxf(array[4], array[6]); + array[4] = tmp; + tmp = vminf(array[8], array[11]); + array[11] = vmaxf(array[8], array[11]); + array[8] = tmp; + tmp = vminf(array[7], array[12]); + array[12] = vmaxf(array[7], array[12]); + array[7] = tmp; + tmp = vminf(array[5], array[9]); + array[9] = vmaxf(array[5], array[9]); + array[5] = tmp; + tmp = vminf(array[0], array[2]); + array[2] = vmaxf(array[0], array[2]); + array[0] = tmp; + tmp = vminf(array[3], array[7]); + array[7] = vmaxf(array[3], array[7]); + array[3] = tmp; + tmp = vminf(array[10], array[11]); + array[11] = vmaxf(array[10], array[11]); + array[10] = tmp; + tmp = vminf(array[1], array[4]); + array[4] = vmaxf(array[1], array[4]); + array[1] = tmp; + tmp = vminf(array[6], array[12]); + array[12] = vmaxf(array[6], array[12]); + array[6] = tmp; + tmp = vminf(array[7], array[8]); + array[8] = vmaxf(array[7], array[8]); + array[7] = tmp; + array[11] = vminf(array[11], array[12]); + tmp = vminf(array[4], array[9]); + array[9] = vmaxf(array[4], array[9]); + array[4] = tmp; + tmp = vminf(array[6], array[10]); + array[10] = vmaxf(array[6], array[10]); + array[6] = tmp; + tmp = vminf(array[3], array[4]); + array[4] = vmaxf(array[3], array[4]); + array[3] = tmp; + tmp = vminf(array[5], array[6]); + array[6] = vmaxf(array[5], array[6]); + array[5] = tmp; + array[8] = vminf(array[8], array[9]); + array[10] = vminf(array[10], array[11]); + tmp = vminf(array[1], array[7]); + array[7] = vmaxf(array[1], array[7]); + array[1] = tmp; + tmp = vminf(array[2], array[6]); + array[6] = vmaxf(array[2], array[6]); + array[2] = tmp; + array[3] = vmaxf(array[1], array[3]); + tmp = vminf(array[4], array[7]); + array[7] = vmaxf(array[4], array[7]); + array[4] = tmp; + array[8] = vminf(array[8], array[10]); + array[5] = vmaxf(array[0], array[5]); + array[5] = vmaxf(array[2], array[5]); + tmp = vminf(array[6], array[8]); + array[8] = vmaxf(array[6], array[8]); + array[5] = vmaxf(array[3], array[5]); + array[7] = vminf(array[7], array[8]); + array[6] = vmaxf(array[4], tmp); + tmp = vminf(array[4], tmp); + array[5] = vmaxf(tmp, array[5]); + array[6] = vminf(array[6], array[7]); + return vmaxf(array[5], array[6]); +} +#endif + +template +inline T median(std::array array) +{ + T tmp = std::min(array[0], array[1]); + array[1] = std::max(array[0], array[1]); + array[0] = tmp; + tmp = std::min(array[3], array[4]); + array[4] = std::max(array[3], array[4]); + array[3] = tmp; + tmp = std::min(array[2], array[4]); + array[4] = std::max(array[2], array[4]); + array[2] = std::min(tmp, array[3]); + array[3] = std::max(tmp, array[3]); + tmp = std::min(array[6], array[7]); + array[7] = std::max(array[6], array[7]); + array[6] = tmp; + tmp = std::min(array[5], array[7]); + array[7] = std::max(array[5], array[7]); + array[5] = std::min(tmp, array[6]); + array[6] = std::max(tmp, array[6]); + tmp = std::min(array[9], array[10]); + array[10] = std::max(array[9], array[10]); + array[9] = tmp; + tmp = std::min(array[8], array[10]); + array[10] = std::max(array[8], array[10]); + array[8] = std::min(tmp, array[9]); + array[9] = std::max(tmp, array[9]); + tmp = std::min(array[12], array[13]); + array[13] = std::max(array[12], array[13]); + array[12] = tmp; + tmp = std::min(array[11], array[13]); + array[13] = std::max(array[11], array[13]); + array[11] = std::min(tmp, array[12]); + array[12] = std::max(tmp, array[12]); + tmp = std::min(array[15], array[16]); + array[16] = std::max(array[15], array[16]); + array[15] = tmp; + tmp = std::min(array[14], array[16]); + array[16] = std::max(array[14], array[16]); + array[14] = std::min(tmp, array[15]); + array[15] = std::max(tmp, array[15]); + tmp = std::min(array[18], array[19]); + array[19] = std::max(array[18], array[19]); + array[18] = tmp; + tmp = std::min(array[17], array[19]); + array[19] = std::max(array[17], array[19]); + array[17] = std::min(tmp, array[18]); + array[18] = std::max(tmp, array[18]); + tmp = std::min(array[21], array[22]); + array[22] = std::max(array[21], array[22]); + array[21] = tmp; + tmp = std::min(array[20], array[22]); + array[22] = std::max(array[20], array[22]); + array[20] = std::min(tmp, array[21]); + array[21] = std::max(tmp, array[21]); + tmp = std::min(array[23], array[24]); + array[24] = std::max(array[23], array[24]); + array[23] = tmp; + tmp = std::min(array[2], array[5]); + array[5] = std::max(array[2], array[5]); + array[2] = tmp; + tmp = std::min(array[3], array[6]); + array[6] = std::max(array[3], array[6]); + array[3] = tmp; + tmp = std::min(array[0], array[6]); + array[6] = std::max(array[0], array[6]); + array[0] = std::min(tmp, array[3]); + array[3] = std::max(tmp, array[3]); + tmp = std::min(array[4], array[7]); + array[7] = std::max(array[4], array[7]); + array[4] = tmp; + tmp = std::min(array[1], array[7]); + array[7] = std::max(array[1], array[7]); + array[1] = std::min(tmp, array[4]); + array[4] = std::max(tmp, array[4]); + tmp = std::min(array[11], array[14]); + array[14] = std::max(array[11], array[14]); + array[11] = tmp; + tmp = std::min(array[8], array[14]); + array[14] = std::max(array[8], array[14]); + array[8] = std::min(tmp, array[11]); + array[11] = std::max(tmp, array[11]); + tmp = std::min(array[12], array[15]); + array[15] = std::max(array[12], array[15]); + array[12] = tmp; + tmp = std::min(array[9], array[15]); + array[15] = std::max(array[9], array[15]); + array[9] = std::min(tmp, array[12]); + array[12] = std::max(tmp, array[12]); + tmp = std::min(array[13], array[16]); + array[16] = std::max(array[13], array[16]); + array[13] = tmp; + tmp = std::min(array[10], array[16]); + array[16] = std::max(array[10], array[16]); + array[10] = std::min(tmp, array[13]); + array[13] = std::max(tmp, array[13]); + tmp = std::min(array[20], array[23]); + array[23] = std::max(array[20], array[23]); + array[20] = tmp; + tmp = std::min(array[17], array[23]); + array[23] = std::max(array[17], array[23]); + array[17] = std::min(tmp, array[20]); + array[20] = std::max(tmp, array[20]); + tmp = std::min(array[21], array[24]); + array[24] = std::max(array[21], array[24]); + array[21] = tmp; + tmp = std::min(array[18], array[24]); + array[24] = std::max(array[18], array[24]); + array[18] = std::min(tmp, array[21]); + array[21] = std::max(tmp, array[21]); + tmp = std::min(array[19], array[22]); + array[22] = std::max(array[19], array[22]); + array[19] = tmp; + array[17] = std::max(array[8], array[17]); + tmp = std::min(array[9], array[18]); + array[18] = std::max(array[9], array[18]); + array[9] = tmp; + tmp = std::min(array[0], array[18]); + array[18] = std::max(array[0], array[18]); + array[9] = std::max(tmp, array[9]); + tmp = std::min(array[10], array[19]); + array[19] = std::max(array[10], array[19]); + array[10] = tmp; + tmp = std::min(array[1], array[19]); + array[19] = std::max(array[1], array[19]); + array[1] = std::min(tmp, array[10]); + array[10] = std::max(tmp, array[10]); + tmp = std::min(array[11], array[20]); + array[20] = std::max(array[11], array[20]); + array[11] = tmp; + tmp = std::min(array[2], array[20]); + array[20] = std::max(array[2], array[20]); + array[11] = std::max(tmp, array[11]); + tmp = std::min(array[12], array[21]); + array[21] = std::max(array[12], array[21]); + array[12] = tmp; + tmp = std::min(array[3], array[21]); + array[21] = std::max(array[3], array[21]); + array[3] = std::min(tmp, array[12]); + array[12] = std::max(tmp, array[12]); + tmp = std::min(array[13], array[22]); + array[22] = std::max(array[13], array[22]); + array[4] = std::min(array[4], array[22]); + array[13] = std::max(array[4], tmp); + tmp = std::min(array[4], tmp); + array[4] = tmp; + tmp = std::min(array[14], array[23]); + array[23] = std::max(array[14], array[23]); + array[14] = tmp; + tmp = std::min(array[5], array[23]); + array[23] = std::max(array[5], array[23]); + array[5] = std::min(tmp, array[14]); + array[14] = std::max(tmp, array[14]); + tmp = std::min(array[15], array[24]); + array[24] = std::max(array[15], array[24]); + array[15] = tmp; + array[6] = std::min(array[6], array[24]); + tmp = std::min(array[6], array[15]); + array[15] = std::max(array[6], array[15]); + array[6] = tmp; + tmp = std::min(array[7], array[16]); + array[7] = std::min(tmp, array[19]); + tmp = std::min(array[13], array[21]); + array[15] = std::min(array[15], array[23]); + tmp = std::min(array[7], tmp); + array[7] = std::min(tmp, array[15]); + array[9] = std::max(array[1], array[9]); + array[11] = std::max(array[3], array[11]); + array[17] = std::max(array[5], array[17]); + array[17] = std::max(array[11], array[17]); + array[17] = std::max(array[9], array[17]); + tmp = std::min(array[4], array[10]); + array[10] = std::max(array[4], array[10]); + array[4] = tmp; + tmp = std::min(array[6], array[12]); + array[12] = std::max(array[6], array[12]); + array[6] = tmp; + tmp = std::min(array[7], array[14]); + array[14] = std::max(array[7], array[14]); + array[7] = tmp; + tmp = std::min(array[4], array[6]); + array[6] = std::max(array[4], array[6]); + array[7] = std::max(tmp, array[7]); + tmp = std::min(array[12], array[14]); + array[14] = std::max(array[12], array[14]); + array[12] = tmp; + array[10] = std::min(array[10], array[14]); + tmp = std::min(array[6], array[7]); + array[7] = std::max(array[6], array[7]); + array[6] = tmp; + tmp = std::min(array[10], array[12]); + array[12] = std::max(array[10], array[12]); + array[10] = std::max(array[6], tmp); + tmp = std::min(array[6], tmp); + array[17] = std::max(tmp, array[17]); + tmp = std::min(array[12], array[17]); + array[17] = std::max(array[12], array[17]); + array[12] = tmp; + array[7] = std::min(array[7], array[17]); + tmp = std::min(array[7], array[10]); + array[10] = std::max(array[7], array[10]); + array[7] = tmp; + tmp = std::min(array[12], array[18]); + array[18] = std::max(array[12], array[18]); + array[12] = std::max(array[7], tmp); + array[10] = std::min(array[10], array[18]); + tmp = std::min(array[12], array[20]); + array[20] = std::max(array[12], array[20]); + array[12] = tmp; + tmp = std::min(array[10], array[20]); + return std::max(tmp, array[12]); +} + +#ifdef __SSE2__ +template<> +inline vfloat median(std::array array) +{ + vfloat tmp = vminf(array[0], array[1]); + array[1] = vmaxf(array[0], array[1]); + array[0] = tmp; + tmp = vminf(array[3], array[4]); + array[4] = vmaxf(array[3], array[4]); + array[3] = tmp; + tmp = vminf(array[2], array[4]); + array[4] = vmaxf(array[2], array[4]); + array[2] = vminf(tmp, array[3]); + array[3] = vmaxf(tmp, array[3]); + tmp = vminf(array[6], array[7]); + array[7] = vmaxf(array[6], array[7]); + array[6] = tmp; + tmp = vminf(array[5], array[7]); + array[7] = vmaxf(array[5], array[7]); + array[5] = vminf(tmp, array[6]); + array[6] = vmaxf(tmp, array[6]); + tmp = vminf(array[9], array[10]); + array[10] = vmaxf(array[9], array[10]); + array[9] = tmp; + tmp = vminf(array[8], array[10]); + array[10] = vmaxf(array[8], array[10]); + array[8] = vminf(tmp, array[9]); + array[9] = vmaxf(tmp, array[9]); + tmp = vminf(array[12], array[13]); + array[13] = vmaxf(array[12], array[13]); + array[12] = tmp; + tmp = vminf(array[11], array[13]); + array[13] = vmaxf(array[11], array[13]); + array[11] = vminf(tmp, array[12]); + array[12] = vmaxf(tmp, array[12]); + tmp = vminf(array[15], array[16]); + array[16] = vmaxf(array[15], array[16]); + array[15] = tmp; + tmp = vminf(array[14], array[16]); + array[16] = vmaxf(array[14], array[16]); + array[14] = vminf(tmp, array[15]); + array[15] = vmaxf(tmp, array[15]); + tmp = vminf(array[18], array[19]); + array[19] = vmaxf(array[18], array[19]); + array[18] = tmp; + tmp = vminf(array[17], array[19]); + array[19] = vmaxf(array[17], array[19]); + array[17] = vminf(tmp, array[18]); + array[18] = vmaxf(tmp, array[18]); + tmp = vminf(array[21], array[22]); + array[22] = vmaxf(array[21], array[22]); + array[21] = tmp; + tmp = vminf(array[20], array[22]); + array[22] = vmaxf(array[20], array[22]); + array[20] = vminf(tmp, array[21]); + array[21] = vmaxf(tmp, array[21]); + tmp = vminf(array[23], array[24]); + array[24] = vmaxf(array[23], array[24]); + array[23] = tmp; + tmp = vminf(array[2], array[5]); + array[5] = vmaxf(array[2], array[5]); + array[2] = tmp; + tmp = vminf(array[3], array[6]); + array[6] = vmaxf(array[3], array[6]); + array[3] = tmp; + tmp = vminf(array[0], array[6]); + array[6] = vmaxf(array[0], array[6]); + array[0] = vminf(tmp, array[3]); + array[3] = vmaxf(tmp, array[3]); + tmp = vminf(array[4], array[7]); + array[7] = vmaxf(array[4], array[7]); + array[4] = tmp; + tmp = vminf(array[1], array[7]); + array[7] = vmaxf(array[1], array[7]); + array[1] = vminf(tmp, array[4]); + array[4] = vmaxf(tmp, array[4]); + tmp = vminf(array[11], array[14]); + array[14] = vmaxf(array[11], array[14]); + array[11] = tmp; + tmp = vminf(array[8], array[14]); + array[14] = vmaxf(array[8], array[14]); + array[8] = vminf(tmp, array[11]); + array[11] = vmaxf(tmp, array[11]); + tmp = vminf(array[12], array[15]); + array[15] = vmaxf(array[12], array[15]); + array[12] = tmp; + tmp = vminf(array[9], array[15]); + array[15] = vmaxf(array[9], array[15]); + array[9] = vminf(tmp, array[12]); + array[12] = vmaxf(tmp, array[12]); + tmp = vminf(array[13], array[16]); + array[16] = vmaxf(array[13], array[16]); + array[13] = tmp; + tmp = vminf(array[10], array[16]); + array[16] = vmaxf(array[10], array[16]); + array[10] = vminf(tmp, array[13]); + array[13] = vmaxf(tmp, array[13]); + tmp = vminf(array[20], array[23]); + array[23] = vmaxf(array[20], array[23]); + array[20] = tmp; + tmp = vminf(array[17], array[23]); + array[23] = vmaxf(array[17], array[23]); + array[17] = vminf(tmp, array[20]); + array[20] = vmaxf(tmp, array[20]); + tmp = vminf(array[21], array[24]); + array[24] = vmaxf(array[21], array[24]); + array[21] = tmp; + tmp = vminf(array[18], array[24]); + array[24] = vmaxf(array[18], array[24]); + array[18] = vminf(tmp, array[21]); + array[21] = vmaxf(tmp, array[21]); + tmp = vminf(array[19], array[22]); + array[22] = vmaxf(array[19], array[22]); + array[19] = tmp; + array[17] = vmaxf(array[8], array[17]); + tmp = vminf(array[9], array[18]); + array[18] = vmaxf(array[9], array[18]); + array[9] = tmp; + tmp = vminf(array[0], array[18]); + array[18] = vmaxf(array[0], array[18]); + array[9] = vmaxf(tmp, array[9]); + tmp = vminf(array[10], array[19]); + array[19] = vmaxf(array[10], array[19]); + array[10] = tmp; + tmp = vminf(array[1], array[19]); + array[19] = vmaxf(array[1], array[19]); + array[1] = vminf(tmp, array[10]); + array[10] = vmaxf(tmp, array[10]); + tmp = vminf(array[11], array[20]); + array[20] = vmaxf(array[11], array[20]); + array[11] = tmp; + tmp = vminf(array[2], array[20]); + array[20] = vmaxf(array[2], array[20]); + array[11] = vmaxf(tmp, array[11]); + tmp = vminf(array[12], array[21]); + array[21] = vmaxf(array[12], array[21]); + array[12] = tmp; + tmp = vminf(array[3], array[21]); + array[21] = vmaxf(array[3], array[21]); + array[3] = vminf(tmp, array[12]); + array[12] = vmaxf(tmp, array[12]); + tmp = vminf(array[13], array[22]); + array[22] = vmaxf(array[13], array[22]); + array[4] = vminf(array[4], array[22]); + array[13] = vmaxf(array[4], tmp); + tmp = vminf(array[4], tmp); + array[4] = tmp; + tmp = vminf(array[14], array[23]); + array[23] = vmaxf(array[14], array[23]); + array[14] = tmp; + tmp = vminf(array[5], array[23]); + array[23] = vmaxf(array[5], array[23]); + array[5] = vminf(tmp, array[14]); + array[14] = vmaxf(tmp, array[14]); + tmp = vminf(array[15], array[24]); + array[24] = vmaxf(array[15], array[24]); + array[15] = tmp; + array[6] = vminf(array[6], array[24]); + tmp = vminf(array[6], array[15]); + array[15] = vmaxf(array[6], array[15]); + array[6] = tmp; + tmp = vminf(array[7], array[16]); + array[7] = vminf(tmp, array[19]); + tmp = vminf(array[13], array[21]); + array[15] = vminf(array[15], array[23]); + tmp = vminf(array[7], tmp); + array[7] = vminf(tmp, array[15]); + array[9] = vmaxf(array[1], array[9]); + array[11] = vmaxf(array[3], array[11]); + array[17] = vmaxf(array[5], array[17]); + array[17] = vmaxf(array[11], array[17]); + array[17] = vmaxf(array[9], array[17]); + tmp = vminf(array[4], array[10]); + array[10] = vmaxf(array[4], array[10]); + array[4] = tmp; + tmp = vminf(array[6], array[12]); + array[12] = vmaxf(array[6], array[12]); + array[6] = tmp; + tmp = vminf(array[7], array[14]); + array[14] = vmaxf(array[7], array[14]); + array[7] = tmp; + tmp = vminf(array[4], array[6]); + array[6] = vmaxf(array[4], array[6]); + array[7] = vmaxf(tmp, array[7]); + tmp = vminf(array[12], array[14]); + array[14] = vmaxf(array[12], array[14]); + array[12] = tmp; + array[10] = vminf(array[10], array[14]); + tmp = vminf(array[6], array[7]); + array[7] = vmaxf(array[6], array[7]); + array[6] = tmp; + tmp = vminf(array[10], array[12]); + array[12] = vmaxf(array[10], array[12]); + array[10] = vmaxf(array[6], tmp); + tmp = vminf(array[6], tmp); + array[17] = vmaxf(tmp, array[17]); + tmp = vminf(array[12], array[17]); + array[17] = vmaxf(array[12], array[17]); + array[12] = tmp; + array[7] = vminf(array[7], array[17]); + tmp = vminf(array[7], array[10]); + array[10] = vmaxf(array[7], array[10]); + array[7] = tmp; + tmp = vminf(array[12], array[18]); + array[18] = vmaxf(array[12], array[18]); + array[12] = vmaxf(array[7], tmp); + array[10] = vminf(array[10], array[18]); + tmp = vminf(array[12], array[20]); + array[20] = vmaxf(array[12], array[20]); + array[12] = tmp; + tmp = vminf(array[10], array[20]); + return vmaxf(tmp, array[12]); +} +#endif + +template +inline T median(std::array array) +{ + T tmp = std::min(array[0], array[32]); + array[32] = std::max(array[0], array[32]); + array[0] = tmp; + tmp = std::min(array[1], array[33]); + array[33] = std::max(array[1], array[33]); + array[1] = tmp; + tmp = std::min(array[2], array[34]); + array[34] = std::max(array[2], array[34]); + array[2] = tmp; + tmp = std::min(array[3], array[35]); + array[35] = std::max(array[3], array[35]); + array[3] = tmp; + tmp = std::min(array[4], array[36]); + array[36] = std::max(array[4], array[36]); + array[4] = tmp; + tmp = std::min(array[5], array[37]); + array[37] = std::max(array[5], array[37]); + array[5] = tmp; + tmp = std::min(array[6], array[38]); + array[38] = std::max(array[6], array[38]); + array[6] = tmp; + tmp = std::min(array[7], array[39]); + array[39] = std::max(array[7], array[39]); + array[7] = tmp; + tmp = std::min(array[8], array[40]); + array[40] = std::max(array[8], array[40]); + array[8] = tmp; + tmp = std::min(array[9], array[41]); + array[41] = std::max(array[9], array[41]); + array[9] = tmp; + tmp = std::min(array[10], array[42]); + array[42] = std::max(array[10], array[42]); + array[10] = tmp; + tmp = std::min(array[11], array[43]); + array[43] = std::max(array[11], array[43]); + array[11] = tmp; + tmp = std::min(array[12], array[44]); + array[44] = std::max(array[12], array[44]); + array[12] = tmp; + tmp = std::min(array[13], array[45]); + array[45] = std::max(array[13], array[45]); + array[13] = tmp; + tmp = std::min(array[14], array[46]); + array[46] = std::max(array[14], array[46]); + array[14] = tmp; + tmp = std::min(array[15], array[47]); + array[47] = std::max(array[15], array[47]); + array[15] = tmp; + tmp = std::min(array[16], array[48]); + array[48] = std::max(array[16], array[48]); + array[16] = tmp; + tmp = std::min(array[0], array[16]); + array[16] = std::max(array[0], array[16]); + array[0] = tmp; + tmp = std::min(array[1], array[17]); + array[17] = std::max(array[1], array[17]); + array[1] = tmp; + tmp = std::min(array[2], array[18]); + array[18] = std::max(array[2], array[18]); + array[2] = tmp; + tmp = std::min(array[3], array[19]); + array[19] = std::max(array[3], array[19]); + array[3] = tmp; + tmp = std::min(array[4], array[20]); + array[20] = std::max(array[4], array[20]); + array[4] = tmp; + tmp = std::min(array[5], array[21]); + array[21] = std::max(array[5], array[21]); + array[5] = tmp; + tmp = std::min(array[6], array[22]); + array[22] = std::max(array[6], array[22]); + array[6] = tmp; + tmp = std::min(array[7], array[23]); + array[23] = std::max(array[7], array[23]); + array[7] = tmp; + tmp = std::min(array[8], array[24]); + array[24] = std::max(array[8], array[24]); + array[8] = tmp; + tmp = std::min(array[9], array[25]); + array[25] = std::max(array[9], array[25]); + array[9] = tmp; + tmp = std::min(array[10], array[26]); + array[26] = std::max(array[10], array[26]); + array[10] = tmp; + tmp = std::min(array[11], array[27]); + array[27] = std::max(array[11], array[27]); + array[11] = tmp; + tmp = std::min(array[12], array[28]); + array[28] = std::max(array[12], array[28]); + array[12] = tmp; + tmp = std::min(array[13], array[29]); + array[29] = std::max(array[13], array[29]); + array[13] = tmp; + tmp = std::min(array[14], array[30]); + array[30] = std::max(array[14], array[30]); + array[14] = tmp; + tmp = std::min(array[15], array[31]); + array[31] = std::max(array[15], array[31]); + array[15] = tmp; + tmp = std::min(array[32], array[48]); + array[48] = std::max(array[32], array[48]); + array[32] = tmp; + tmp = std::min(array[16], array[32]); + array[32] = std::max(array[16], array[32]); + array[16] = tmp; + tmp = std::min(array[17], array[33]); + array[33] = std::max(array[17], array[33]); + array[17] = tmp; + tmp = std::min(array[18], array[34]); + array[34] = std::max(array[18], array[34]); + array[18] = tmp; + tmp = std::min(array[19], array[35]); + array[35] = std::max(array[19], array[35]); + array[19] = tmp; + tmp = std::min(array[20], array[36]); + array[36] = std::max(array[20], array[36]); + array[20] = tmp; + tmp = std::min(array[21], array[37]); + array[37] = std::max(array[21], array[37]); + array[21] = tmp; + tmp = std::min(array[22], array[38]); + array[38] = std::max(array[22], array[38]); + array[22] = tmp; + tmp = std::min(array[23], array[39]); + array[39] = std::max(array[23], array[39]); + array[23] = tmp; + tmp = std::min(array[24], array[40]); + array[40] = std::max(array[24], array[40]); + array[24] = tmp; + tmp = std::min(array[25], array[41]); + array[41] = std::max(array[25], array[41]); + array[25] = tmp; + tmp = std::min(array[26], array[42]); + array[42] = std::max(array[26], array[42]); + array[26] = tmp; + tmp = std::min(array[27], array[43]); + array[43] = std::max(array[27], array[43]); + array[27] = tmp; + tmp = std::min(array[28], array[44]); + array[44] = std::max(array[28], array[44]); + array[28] = tmp; + tmp = std::min(array[29], array[45]); + array[45] = std::max(array[29], array[45]); + array[29] = tmp; + tmp = std::min(array[30], array[46]); + array[46] = std::max(array[30], array[46]); + array[30] = tmp; + tmp = std::min(array[31], array[47]); + array[47] = std::max(array[31], array[47]); + array[31] = tmp; + tmp = std::min(array[0], array[8]); + array[8] = std::max(array[0], array[8]); + array[0] = tmp; + tmp = std::min(array[1], array[9]); + array[9] = std::max(array[1], array[9]); + array[1] = tmp; + tmp = std::min(array[2], array[10]); + array[10] = std::max(array[2], array[10]); + array[2] = tmp; + tmp = std::min(array[3], array[11]); + array[11] = std::max(array[3], array[11]); + array[3] = tmp; + tmp = std::min(array[4], array[12]); + array[12] = std::max(array[4], array[12]); + array[4] = tmp; + tmp = std::min(array[5], array[13]); + array[13] = std::max(array[5], array[13]); + array[5] = tmp; + tmp = std::min(array[6], array[14]); + array[14] = std::max(array[6], array[14]); + array[6] = tmp; + tmp = std::min(array[7], array[15]); + array[15] = std::max(array[7], array[15]); + array[7] = tmp; + tmp = std::min(array[16], array[24]); + array[24] = std::max(array[16], array[24]); + array[16] = tmp; + tmp = std::min(array[17], array[25]); + array[25] = std::max(array[17], array[25]); + array[17] = tmp; + tmp = std::min(array[18], array[26]); + array[26] = std::max(array[18], array[26]); + array[18] = tmp; + tmp = std::min(array[19], array[27]); + array[27] = std::max(array[19], array[27]); + array[19] = tmp; + tmp = std::min(array[20], array[28]); + array[28] = std::max(array[20], array[28]); + array[20] = tmp; + tmp = std::min(array[21], array[29]); + array[29] = std::max(array[21], array[29]); + array[21] = tmp; + tmp = std::min(array[22], array[30]); + array[30] = std::max(array[22], array[30]); + array[22] = tmp; + tmp = std::min(array[23], array[31]); + array[31] = std::max(array[23], array[31]); + array[23] = tmp; + tmp = std::min(array[32], array[40]); + array[40] = std::max(array[32], array[40]); + array[32] = tmp; + tmp = std::min(array[33], array[41]); + array[41] = std::max(array[33], array[41]); + array[33] = tmp; + tmp = std::min(array[34], array[42]); + array[42] = std::max(array[34], array[42]); + array[34] = tmp; + tmp = std::min(array[35], array[43]); + array[43] = std::max(array[35], array[43]); + array[35] = tmp; + tmp = std::min(array[36], array[44]); + array[44] = std::max(array[36], array[44]); + array[36] = tmp; + tmp = std::min(array[37], array[45]); + array[45] = std::max(array[37], array[45]); + array[37] = tmp; + tmp = std::min(array[38], array[46]); + array[46] = std::max(array[38], array[46]); + array[38] = tmp; + tmp = std::min(array[39], array[47]); + array[47] = std::max(array[39], array[47]); + array[39] = tmp; + tmp = std::min(array[8], array[32]); + array[32] = std::max(array[8], array[32]); + array[8] = tmp; + tmp = std::min(array[9], array[33]); + array[33] = std::max(array[9], array[33]); + array[9] = tmp; + tmp = std::min(array[10], array[34]); + array[34] = std::max(array[10], array[34]); + array[10] = tmp; + tmp = std::min(array[11], array[35]); + array[35] = std::max(array[11], array[35]); + array[11] = tmp; + tmp = std::min(array[12], array[36]); + array[36] = std::max(array[12], array[36]); + array[12] = tmp; + tmp = std::min(array[13], array[37]); + array[37] = std::max(array[13], array[37]); + array[13] = tmp; + tmp = std::min(array[14], array[38]); + array[38] = std::max(array[14], array[38]); + array[14] = tmp; + tmp = std::min(array[15], array[39]); + array[39] = std::max(array[15], array[39]); + array[15] = tmp; + tmp = std::min(array[24], array[48]); + array[48] = std::max(array[24], array[48]); + array[24] = tmp; + tmp = std::min(array[8], array[16]); + array[16] = std::max(array[8], array[16]); + array[8] = tmp; + tmp = std::min(array[9], array[17]); + array[17] = std::max(array[9], array[17]); + array[9] = tmp; + tmp = std::min(array[10], array[18]); + array[18] = std::max(array[10], array[18]); + array[10] = tmp; + tmp = std::min(array[11], array[19]); + array[19] = std::max(array[11], array[19]); + array[11] = tmp; + tmp = std::min(array[12], array[20]); + array[20] = std::max(array[12], array[20]); + array[12] = tmp; + tmp = std::min(array[13], array[21]); + array[21] = std::max(array[13], array[21]); + array[13] = tmp; + tmp = std::min(array[14], array[22]); + array[22] = std::max(array[14], array[22]); + array[14] = tmp; + tmp = std::min(array[15], array[23]); + array[23] = std::max(array[15], array[23]); + array[15] = tmp; + tmp = std::min(array[24], array[32]); + array[32] = std::max(array[24], array[32]); + array[24] = tmp; + tmp = std::min(array[25], array[33]); + array[33] = std::max(array[25], array[33]); + array[25] = tmp; + tmp = std::min(array[26], array[34]); + array[34] = std::max(array[26], array[34]); + array[26] = tmp; + tmp = std::min(array[27], array[35]); + array[35] = std::max(array[27], array[35]); + array[27] = tmp; + tmp = std::min(array[28], array[36]); + array[36] = std::max(array[28], array[36]); + array[28] = tmp; + tmp = std::min(array[29], array[37]); + array[37] = std::max(array[29], array[37]); + array[29] = tmp; + tmp = std::min(array[30], array[38]); + array[38] = std::max(array[30], array[38]); + array[30] = tmp; + tmp = std::min(array[31], array[39]); + array[39] = std::max(array[31], array[39]); + array[31] = tmp; + tmp = std::min(array[40], array[48]); + array[48] = std::max(array[40], array[48]); + array[40] = tmp; + tmp = std::min(array[0], array[4]); + array[4] = std::max(array[0], array[4]); + array[0] = tmp; + tmp = std::min(array[1], array[5]); + array[5] = std::max(array[1], array[5]); + array[1] = tmp; + tmp = std::min(array[2], array[6]); + array[6] = std::max(array[2], array[6]); + array[2] = tmp; + tmp = std::min(array[3], array[7]); + array[7] = std::max(array[3], array[7]); + array[3] = tmp; + tmp = std::min(array[8], array[12]); + array[12] = std::max(array[8], array[12]); + array[8] = tmp; + tmp = std::min(array[9], array[13]); + array[13] = std::max(array[9], array[13]); + array[9] = tmp; + tmp = std::min(array[10], array[14]); + array[14] = std::max(array[10], array[14]); + array[10] = tmp; + tmp = std::min(array[11], array[15]); + array[15] = std::max(array[11], array[15]); + array[11] = tmp; + tmp = std::min(array[16], array[20]); + array[20] = std::max(array[16], array[20]); + array[16] = tmp; + tmp = std::min(array[17], array[21]); + array[21] = std::max(array[17], array[21]); + array[17] = tmp; + tmp = std::min(array[18], array[22]); + array[22] = std::max(array[18], array[22]); + array[18] = tmp; + tmp = std::min(array[19], array[23]); + array[23] = std::max(array[19], array[23]); + array[19] = tmp; + tmp = std::min(array[24], array[28]); + array[28] = std::max(array[24], array[28]); + array[24] = tmp; + tmp = std::min(array[25], array[29]); + array[29] = std::max(array[25], array[29]); + array[25] = tmp; + tmp = std::min(array[26], array[30]); + array[30] = std::max(array[26], array[30]); + array[26] = tmp; + tmp = std::min(array[27], array[31]); + array[31] = std::max(array[27], array[31]); + array[27] = tmp; + tmp = std::min(array[32], array[36]); + array[36] = std::max(array[32], array[36]); + array[32] = tmp; + tmp = std::min(array[33], array[37]); + array[37] = std::max(array[33], array[37]); + array[33] = tmp; + tmp = std::min(array[34], array[38]); + array[38] = std::max(array[34], array[38]); + array[34] = tmp; + tmp = std::min(array[35], array[39]); + array[39] = std::max(array[35], array[39]); + array[35] = tmp; + tmp = std::min(array[40], array[44]); + array[44] = std::max(array[40], array[44]); + array[40] = tmp; + tmp = std::min(array[41], array[45]); + array[45] = std::max(array[41], array[45]); + array[41] = tmp; + tmp = std::min(array[42], array[46]); + array[46] = std::max(array[42], array[46]); + array[42] = tmp; + tmp = std::min(array[43], array[47]); + array[47] = std::max(array[43], array[47]); + array[43] = tmp; + tmp = std::min(array[4], array[32]); + array[32] = std::max(array[4], array[32]); + array[4] = tmp; + tmp = std::min(array[5], array[33]); + array[33] = std::max(array[5], array[33]); + array[5] = tmp; + tmp = std::min(array[6], array[34]); + array[34] = std::max(array[6], array[34]); + array[6] = tmp; + tmp = std::min(array[7], array[35]); + array[35] = std::max(array[7], array[35]); + array[7] = tmp; + tmp = std::min(array[12], array[40]); + array[40] = std::max(array[12], array[40]); + array[12] = tmp; + tmp = std::min(array[13], array[41]); + array[41] = std::max(array[13], array[41]); + array[13] = tmp; + tmp = std::min(array[14], array[42]); + array[42] = std::max(array[14], array[42]); + array[14] = tmp; + tmp = std::min(array[15], array[43]); + array[43] = std::max(array[15], array[43]); + array[15] = tmp; + tmp = std::min(array[20], array[48]); + array[48] = std::max(array[20], array[48]); + array[20] = tmp; + tmp = std::min(array[4], array[16]); + array[16] = std::max(array[4], array[16]); + array[4] = tmp; + tmp = std::min(array[5], array[17]); + array[17] = std::max(array[5], array[17]); + array[5] = tmp; + tmp = std::min(array[6], array[18]); + array[18] = std::max(array[6], array[18]); + array[6] = tmp; + tmp = std::min(array[7], array[19]); + array[19] = std::max(array[7], array[19]); + array[7] = tmp; + tmp = std::min(array[12], array[24]); + array[24] = std::max(array[12], array[24]); + array[12] = tmp; + tmp = std::min(array[13], array[25]); + array[25] = std::max(array[13], array[25]); + array[13] = tmp; + tmp = std::min(array[14], array[26]); + array[26] = std::max(array[14], array[26]); + array[14] = tmp; + tmp = std::min(array[15], array[27]); + array[27] = std::max(array[15], array[27]); + array[15] = tmp; + tmp = std::min(array[20], array[32]); + array[32] = std::max(array[20], array[32]); + array[20] = tmp; + tmp = std::min(array[21], array[33]); + array[33] = std::max(array[21], array[33]); + array[21] = tmp; + tmp = std::min(array[22], array[34]); + array[34] = std::max(array[22], array[34]); + array[22] = tmp; + tmp = std::min(array[23], array[35]); + array[35] = std::max(array[23], array[35]); + array[23] = tmp; + tmp = std::min(array[28], array[40]); + array[40] = std::max(array[28], array[40]); + array[28] = tmp; + tmp = std::min(array[29], array[41]); + array[41] = std::max(array[29], array[41]); + array[29] = tmp; + tmp = std::min(array[30], array[42]); + array[42] = std::max(array[30], array[42]); + array[30] = tmp; + tmp = std::min(array[31], array[43]); + array[43] = std::max(array[31], array[43]); + array[31] = tmp; + tmp = std::min(array[36], array[48]); + array[48] = std::max(array[36], array[48]); + array[36] = tmp; + tmp = std::min(array[4], array[8]); + array[8] = std::max(array[4], array[8]); + array[4] = tmp; + tmp = std::min(array[5], array[9]); + array[9] = std::max(array[5], array[9]); + array[5] = tmp; + tmp = std::min(array[6], array[10]); + array[10] = std::max(array[6], array[10]); + array[6] = tmp; + tmp = std::min(array[7], array[11]); + array[11] = std::max(array[7], array[11]); + array[7] = tmp; + tmp = std::min(array[12], array[16]); + array[16] = std::max(array[12], array[16]); + array[12] = tmp; + tmp = std::min(array[13], array[17]); + array[17] = std::max(array[13], array[17]); + array[13] = tmp; + tmp = std::min(array[14], array[18]); + array[18] = std::max(array[14], array[18]); + array[14] = tmp; + tmp = std::min(array[15], array[19]); + array[19] = std::max(array[15], array[19]); + array[15] = tmp; + tmp = std::min(array[20], array[24]); + array[24] = std::max(array[20], array[24]); + array[20] = tmp; + tmp = std::min(array[21], array[25]); + array[25] = std::max(array[21], array[25]); + array[21] = tmp; + tmp = std::min(array[22], array[26]); + array[26] = std::max(array[22], array[26]); + array[22] = tmp; + tmp = std::min(array[23], array[27]); + array[27] = std::max(array[23], array[27]); + array[23] = tmp; + tmp = std::min(array[28], array[32]); + array[32] = std::max(array[28], array[32]); + array[28] = tmp; + tmp = std::min(array[29], array[33]); + array[33] = std::max(array[29], array[33]); + array[29] = tmp; + tmp = std::min(array[30], array[34]); + array[34] = std::max(array[30], array[34]); + array[30] = tmp; + tmp = std::min(array[31], array[35]); + array[35] = std::max(array[31], array[35]); + array[31] = tmp; + tmp = std::min(array[36], array[40]); + array[40] = std::max(array[36], array[40]); + array[36] = tmp; + tmp = std::min(array[37], array[41]); + array[41] = std::max(array[37], array[41]); + array[37] = tmp; + tmp = std::min(array[38], array[42]); + array[42] = std::max(array[38], array[42]); + array[38] = tmp; + tmp = std::min(array[39], array[43]); + array[43] = std::max(array[39], array[43]); + array[39] = tmp; + tmp = std::min(array[44], array[48]); + array[48] = std::max(array[44], array[48]); + array[44] = tmp; + tmp = std::min(array[0], array[2]); + array[2] = std::max(array[0], array[2]); + array[0] = tmp; + tmp = std::min(array[1], array[3]); + array[3] = std::max(array[1], array[3]); + array[1] = tmp; + tmp = std::min(array[4], array[6]); + array[6] = std::max(array[4], array[6]); + array[4] = tmp; + tmp = std::min(array[5], array[7]); + array[7] = std::max(array[5], array[7]); + array[5] = tmp; + tmp = std::min(array[8], array[10]); + array[10] = std::max(array[8], array[10]); + array[8] = tmp; + tmp = std::min(array[9], array[11]); + array[11] = std::max(array[9], array[11]); + array[9] = tmp; + tmp = std::min(array[12], array[14]); + array[14] = std::max(array[12], array[14]); + array[12] = tmp; + tmp = std::min(array[13], array[15]); + array[15] = std::max(array[13], array[15]); + array[13] = tmp; + tmp = std::min(array[16], array[18]); + array[18] = std::max(array[16], array[18]); + array[16] = tmp; + tmp = std::min(array[17], array[19]); + array[19] = std::max(array[17], array[19]); + array[17] = tmp; + tmp = std::min(array[20], array[22]); + array[22] = std::max(array[20], array[22]); + array[20] = tmp; + tmp = std::min(array[21], array[23]); + array[23] = std::max(array[21], array[23]); + array[21] = tmp; + tmp = std::min(array[24], array[26]); + array[26] = std::max(array[24], array[26]); + array[24] = tmp; + tmp = std::min(array[25], array[27]); + array[27] = std::max(array[25], array[27]); + array[25] = tmp; + tmp = std::min(array[28], array[30]); + array[30] = std::max(array[28], array[30]); + array[28] = tmp; + tmp = std::min(array[29], array[31]); + array[31] = std::max(array[29], array[31]); + array[29] = tmp; + tmp = std::min(array[32], array[34]); + array[34] = std::max(array[32], array[34]); + array[32] = tmp; + tmp = std::min(array[33], array[35]); + array[35] = std::max(array[33], array[35]); + array[33] = tmp; + tmp = std::min(array[36], array[38]); + array[38] = std::max(array[36], array[38]); + array[36] = tmp; + tmp = std::min(array[37], array[39]); + array[39] = std::max(array[37], array[39]); + array[37] = tmp; + tmp = std::min(array[40], array[42]); + array[42] = std::max(array[40], array[42]); + array[40] = tmp; + tmp = std::min(array[41], array[43]); + array[43] = std::max(array[41], array[43]); + array[41] = tmp; + tmp = std::min(array[44], array[46]); + array[46] = std::max(array[44], array[46]); + array[44] = tmp; + tmp = std::min(array[45], array[47]); + array[47] = std::max(array[45], array[47]); + array[45] = tmp; + tmp = std::min(array[2], array[32]); + array[32] = std::max(array[2], array[32]); + array[2] = tmp; + tmp = std::min(array[3], array[33]); + array[33] = std::max(array[3], array[33]); + array[3] = tmp; + tmp = std::min(array[6], array[36]); + array[36] = std::max(array[6], array[36]); + array[6] = tmp; + tmp = std::min(array[7], array[37]); + array[37] = std::max(array[7], array[37]); + array[7] = tmp; + tmp = std::min(array[10], array[40]); + array[40] = std::max(array[10], array[40]); + array[10] = tmp; + tmp = std::min(array[11], array[41]); + array[41] = std::max(array[11], array[41]); + array[11] = tmp; + tmp = std::min(array[14], array[44]); + array[44] = std::max(array[14], array[44]); + array[14] = tmp; + tmp = std::min(array[15], array[45]); + array[45] = std::max(array[15], array[45]); + array[15] = tmp; + tmp = std::min(array[18], array[48]); + array[48] = std::max(array[18], array[48]); + array[18] = tmp; + tmp = std::min(array[2], array[16]); + array[16] = std::max(array[2], array[16]); + array[2] = tmp; + tmp = std::min(array[3], array[17]); + array[17] = std::max(array[3], array[17]); + array[3] = tmp; + tmp = std::min(array[6], array[20]); + array[20] = std::max(array[6], array[20]); + array[6] = tmp; + tmp = std::min(array[7], array[21]); + array[21] = std::max(array[7], array[21]); + array[7] = tmp; + tmp = std::min(array[10], array[24]); + array[24] = std::max(array[10], array[24]); + array[10] = tmp; + tmp = std::min(array[11], array[25]); + array[25] = std::max(array[11], array[25]); + array[11] = tmp; + tmp = std::min(array[14], array[28]); + array[28] = std::max(array[14], array[28]); + array[14] = tmp; + tmp = std::min(array[15], array[29]); + array[29] = std::max(array[15], array[29]); + array[15] = tmp; + tmp = std::min(array[18], array[32]); + array[32] = std::max(array[18], array[32]); + array[18] = tmp; + tmp = std::min(array[19], array[33]); + array[33] = std::max(array[19], array[33]); + array[19] = tmp; + tmp = std::min(array[22], array[36]); + array[36] = std::max(array[22], array[36]); + array[22] = tmp; + tmp = std::min(array[23], array[37]); + array[37] = std::max(array[23], array[37]); + array[23] = tmp; + tmp = std::min(array[26], array[40]); + array[40] = std::max(array[26], array[40]); + array[26] = tmp; + tmp = std::min(array[27], array[41]); + array[41] = std::max(array[27], array[41]); + array[27] = tmp; + tmp = std::min(array[30], array[44]); + array[44] = std::max(array[30], array[44]); + array[30] = tmp; + tmp = std::min(array[31], array[45]); + array[45] = std::max(array[31], array[45]); + array[31] = tmp; + tmp = std::min(array[34], array[48]); + array[48] = std::max(array[34], array[48]); + array[34] = tmp; + tmp = std::min(array[2], array[8]); + array[8] = std::max(array[2], array[8]); + array[2] = tmp; + tmp = std::min(array[3], array[9]); + array[9] = std::max(array[3], array[9]); + array[3] = tmp; + tmp = std::min(array[6], array[12]); + array[12] = std::max(array[6], array[12]); + array[6] = tmp; + tmp = std::min(array[7], array[13]); + array[13] = std::max(array[7], array[13]); + array[7] = tmp; + tmp = std::min(array[10], array[16]); + array[16] = std::max(array[10], array[16]); + array[10] = tmp; + tmp = std::min(array[11], array[17]); + array[17] = std::max(array[11], array[17]); + array[11] = tmp; + tmp = std::min(array[14], array[20]); + array[20] = std::max(array[14], array[20]); + array[14] = tmp; + tmp = std::min(array[15], array[21]); + array[21] = std::max(array[15], array[21]); + array[15] = tmp; + tmp = std::min(array[18], array[24]); + array[24] = std::max(array[18], array[24]); + array[18] = tmp; + tmp = std::min(array[19], array[25]); + array[25] = std::max(array[19], array[25]); + array[19] = tmp; + tmp = std::min(array[22], array[28]); + array[28] = std::max(array[22], array[28]); + array[22] = tmp; + tmp = std::min(array[23], array[29]); + array[29] = std::max(array[23], array[29]); + array[23] = tmp; + tmp = std::min(array[26], array[32]); + array[32] = std::max(array[26], array[32]); + array[26] = tmp; + tmp = std::min(array[27], array[33]); + array[33] = std::max(array[27], array[33]); + array[27] = tmp; + tmp = std::min(array[30], array[36]); + array[36] = std::max(array[30], array[36]); + array[30] = tmp; + tmp = std::min(array[31], array[37]); + array[37] = std::max(array[31], array[37]); + array[31] = tmp; + tmp = std::min(array[34], array[40]); + array[40] = std::max(array[34], array[40]); + array[34] = tmp; + tmp = std::min(array[35], array[41]); + array[41] = std::max(array[35], array[41]); + array[35] = tmp; + tmp = std::min(array[38], array[44]); + array[44] = std::max(array[38], array[44]); + array[38] = tmp; + tmp = std::min(array[39], array[45]); + array[45] = std::max(array[39], array[45]); + array[39] = tmp; + tmp = std::min(array[42], array[48]); + array[48] = std::max(array[42], array[48]); + array[42] = tmp; + tmp = std::min(array[2], array[4]); + array[4] = std::max(array[2], array[4]); + array[2] = tmp; + tmp = std::min(array[3], array[5]); + array[5] = std::max(array[3], array[5]); + array[3] = tmp; + tmp = std::min(array[6], array[8]); + array[8] = std::max(array[6], array[8]); + array[6] = tmp; + tmp = std::min(array[7], array[9]); + array[9] = std::max(array[7], array[9]); + array[7] = tmp; + tmp = std::min(array[10], array[12]); + array[12] = std::max(array[10], array[12]); + array[10] = tmp; + tmp = std::min(array[11], array[13]); + array[13] = std::max(array[11], array[13]); + array[11] = tmp; + tmp = std::min(array[14], array[16]); + array[16] = std::max(array[14], array[16]); + array[14] = tmp; + tmp = std::min(array[15], array[17]); + array[17] = std::max(array[15], array[17]); + array[15] = tmp; + tmp = std::min(array[18], array[20]); + array[20] = std::max(array[18], array[20]); + array[18] = tmp; + tmp = std::min(array[19], array[21]); + array[21] = std::max(array[19], array[21]); + array[19] = tmp; + tmp = std::min(array[22], array[24]); + array[24] = std::max(array[22], array[24]); + array[22] = tmp; + tmp = std::min(array[23], array[25]); + array[25] = std::max(array[23], array[25]); + array[23] = tmp; + tmp = std::min(array[26], array[28]); + array[28] = std::max(array[26], array[28]); + array[26] = tmp; + tmp = std::min(array[27], array[29]); + array[29] = std::max(array[27], array[29]); + array[27] = tmp; + tmp = std::min(array[30], array[32]); + array[32] = std::max(array[30], array[32]); + array[30] = tmp; + tmp = std::min(array[31], array[33]); + array[33] = std::max(array[31], array[33]); + array[31] = tmp; + tmp = std::min(array[34], array[36]); + array[36] = std::max(array[34], array[36]); + array[34] = tmp; + tmp = std::min(array[35], array[37]); + array[37] = std::max(array[35], array[37]); + array[35] = tmp; + tmp = std::min(array[38], array[40]); + array[40] = std::max(array[38], array[40]); + array[38] = tmp; + tmp = std::min(array[39], array[41]); + array[41] = std::max(array[39], array[41]); + array[39] = tmp; + tmp = std::min(array[42], array[44]); + array[44] = std::max(array[42], array[44]); + array[42] = tmp; + tmp = std::min(array[43], array[45]); + array[45] = std::max(array[43], array[45]); + array[43] = tmp; + tmp = std::min(array[46], array[48]); + array[48] = std::max(array[46], array[48]); + array[46] = tmp; + array[1] = std::max(array[0], array[1]); + array[3] = std::max(array[2], array[3]); + array[5] = std::max(array[4], array[5]); + array[7] = std::max(array[6], array[7]); + array[9] = std::max(array[8], array[9]); + array[11] = std::max(array[10], array[11]); + array[13] = std::max(array[12], array[13]); + array[15] = std::max(array[14], array[15]); + array[17] = std::max(array[16], array[17]); + array[19] = std::max(array[18], array[19]); + array[21] = std::max(array[20], array[21]); + array[23] = std::max(array[22], array[23]); + array[24] = std::min(array[24], array[25]); + array[26] = std::min(array[26], array[27]); + array[28] = std::min(array[28], array[29]); + array[30] = std::min(array[30], array[31]); + array[32] = std::min(array[32], array[33]); + array[34] = std::min(array[34], array[35]); + array[36] = std::min(array[36], array[37]); + array[38] = std::min(array[38], array[39]); + array[40] = std::min(array[40], array[41]); + array[42] = std::min(array[42], array[43]); + array[44] = std::min(array[44], array[45]); + array[46] = std::min(array[46], array[47]); + array[32] = std::max(array[1], array[32]); + array[34] = std::max(array[3], array[34]); + array[36] = std::max(array[5], array[36]); + array[38] = std::max(array[7], array[38]); + array[9] = std::min(array[9], array[40]); + array[11] = std::min(array[11], array[42]); + array[13] = std::min(array[13], array[44]); + array[15] = std::min(array[15], array[46]); + array[17] = std::min(array[17], array[48]); + array[24] = std::max(array[9], array[24]); + array[26] = std::max(array[11], array[26]); + array[28] = std::max(array[13], array[28]); + array[30] = std::max(array[15], array[30]); + array[17] = std::min(array[17], array[32]); + array[19] = std::min(array[19], array[34]); + array[21] = std::min(array[21], array[36]); + array[23] = std::min(array[23], array[38]); + array[24] = std::max(array[17], array[24]); + array[26] = std::max(array[19], array[26]); + array[21] = std::min(array[21], array[28]); + array[23] = std::min(array[23], array[30]); + array[24] = std::max(array[21], array[24]); + array[23] = std::min(array[23], array[26]); + return std::max(array[23], array[24]); +} + +#ifdef __SSE2__ +template<> +inline vfloat median(std::array array) +{ + vfloat tmp = vminf(array[0], array[32]); + array[32] = vmaxf(array[0], array[32]); + array[0] = tmp; + tmp = vminf(array[1], array[33]); + array[33] = vmaxf(array[1], array[33]); + array[1] = tmp; + tmp = vminf(array[2], array[34]); + array[34] = vmaxf(array[2], array[34]); + array[2] = tmp; + tmp = vminf(array[3], array[35]); + array[35] = vmaxf(array[3], array[35]); + array[3] = tmp; + tmp = vminf(array[4], array[36]); + array[36] = vmaxf(array[4], array[36]); + array[4] = tmp; + tmp = vminf(array[5], array[37]); + array[37] = vmaxf(array[5], array[37]); + array[5] = tmp; + tmp = vminf(array[6], array[38]); + array[38] = vmaxf(array[6], array[38]); + array[6] = tmp; + tmp = vminf(array[7], array[39]); + array[39] = vmaxf(array[7], array[39]); + array[7] = tmp; + tmp = vminf(array[8], array[40]); + array[40] = vmaxf(array[8], array[40]); + array[8] = tmp; + tmp = vminf(array[9], array[41]); + array[41] = vmaxf(array[9], array[41]); + array[9] = tmp; + tmp = vminf(array[10], array[42]); + array[42] = vmaxf(array[10], array[42]); + array[10] = tmp; + tmp = vminf(array[11], array[43]); + array[43] = vmaxf(array[11], array[43]); + array[11] = tmp; + tmp = vminf(array[12], array[44]); + array[44] = vmaxf(array[12], array[44]); + array[12] = tmp; + tmp = vminf(array[13], array[45]); + array[45] = vmaxf(array[13], array[45]); + array[13] = tmp; + tmp = vminf(array[14], array[46]); + array[46] = vmaxf(array[14], array[46]); + array[14] = tmp; + tmp = vminf(array[15], array[47]); + array[47] = vmaxf(array[15], array[47]); + array[15] = tmp; + tmp = vminf(array[16], array[48]); + array[48] = vmaxf(array[16], array[48]); + array[16] = tmp; + tmp = vminf(array[0], array[16]); + array[16] = vmaxf(array[0], array[16]); + array[0] = tmp; + tmp = vminf(array[1], array[17]); + array[17] = vmaxf(array[1], array[17]); + array[1] = tmp; + tmp = vminf(array[2], array[18]); + array[18] = vmaxf(array[2], array[18]); + array[2] = tmp; + tmp = vminf(array[3], array[19]); + array[19] = vmaxf(array[3], array[19]); + array[3] = tmp; + tmp = vminf(array[4], array[20]); + array[20] = vmaxf(array[4], array[20]); + array[4] = tmp; + tmp = vminf(array[5], array[21]); + array[21] = vmaxf(array[5], array[21]); + array[5] = tmp; + tmp = vminf(array[6], array[22]); + array[22] = vmaxf(array[6], array[22]); + array[6] = tmp; + tmp = vminf(array[7], array[23]); + array[23] = vmaxf(array[7], array[23]); + array[7] = tmp; + tmp = vminf(array[8], array[24]); + array[24] = vmaxf(array[8], array[24]); + array[8] = tmp; + tmp = vminf(array[9], array[25]); + array[25] = vmaxf(array[9], array[25]); + array[9] = tmp; + tmp = vminf(array[10], array[26]); + array[26] = vmaxf(array[10], array[26]); + array[10] = tmp; + tmp = vminf(array[11], array[27]); + array[27] = vmaxf(array[11], array[27]); + array[11] = tmp; + tmp = vminf(array[12], array[28]); + array[28] = vmaxf(array[12], array[28]); + array[12] = tmp; + tmp = vminf(array[13], array[29]); + array[29] = vmaxf(array[13], array[29]); + array[13] = tmp; + tmp = vminf(array[14], array[30]); + array[30] = vmaxf(array[14], array[30]); + array[14] = tmp; + tmp = vminf(array[15], array[31]); + array[31] = vmaxf(array[15], array[31]); + array[15] = tmp; + tmp = vminf(array[32], array[48]); + array[48] = vmaxf(array[32], array[48]); + array[32] = tmp; + tmp = vminf(array[16], array[32]); + array[32] = vmaxf(array[16], array[32]); + array[16] = tmp; + tmp = vminf(array[17], array[33]); + array[33] = vmaxf(array[17], array[33]); + array[17] = tmp; + tmp = vminf(array[18], array[34]); + array[34] = vmaxf(array[18], array[34]); + array[18] = tmp; + tmp = vminf(array[19], array[35]); + array[35] = vmaxf(array[19], array[35]); + array[19] = tmp; + tmp = vminf(array[20], array[36]); + array[36] = vmaxf(array[20], array[36]); + array[20] = tmp; + tmp = vminf(array[21], array[37]); + array[37] = vmaxf(array[21], array[37]); + array[21] = tmp; + tmp = vminf(array[22], array[38]); + array[38] = vmaxf(array[22], array[38]); + array[22] = tmp; + tmp = vminf(array[23], array[39]); + array[39] = vmaxf(array[23], array[39]); + array[23] = tmp; + tmp = vminf(array[24], array[40]); + array[40] = vmaxf(array[24], array[40]); + array[24] = tmp; + tmp = vminf(array[25], array[41]); + array[41] = vmaxf(array[25], array[41]); + array[25] = tmp; + tmp = vminf(array[26], array[42]); + array[42] = vmaxf(array[26], array[42]); + array[26] = tmp; + tmp = vminf(array[27], array[43]); + array[43] = vmaxf(array[27], array[43]); + array[27] = tmp; + tmp = vminf(array[28], array[44]); + array[44] = vmaxf(array[28], array[44]); + array[28] = tmp; + tmp = vminf(array[29], array[45]); + array[45] = vmaxf(array[29], array[45]); + array[29] = tmp; + tmp = vminf(array[30], array[46]); + array[46] = vmaxf(array[30], array[46]); + array[30] = tmp; + tmp = vminf(array[31], array[47]); + array[47] = vmaxf(array[31], array[47]); + array[31] = tmp; + tmp = vminf(array[0], array[8]); + array[8] = vmaxf(array[0], array[8]); + array[0] = tmp; + tmp = vminf(array[1], array[9]); + array[9] = vmaxf(array[1], array[9]); + array[1] = tmp; + tmp = vminf(array[2], array[10]); + array[10] = vmaxf(array[2], array[10]); + array[2] = tmp; + tmp = vminf(array[3], array[11]); + array[11] = vmaxf(array[3], array[11]); + array[3] = tmp; + tmp = vminf(array[4], array[12]); + array[12] = vmaxf(array[4], array[12]); + array[4] = tmp; + tmp = vminf(array[5], array[13]); + array[13] = vmaxf(array[5], array[13]); + array[5] = tmp; + tmp = vminf(array[6], array[14]); + array[14] = vmaxf(array[6], array[14]); + array[6] = tmp; + tmp = vminf(array[7], array[15]); + array[15] = vmaxf(array[7], array[15]); + array[7] = tmp; + tmp = vminf(array[16], array[24]); + array[24] = vmaxf(array[16], array[24]); + array[16] = tmp; + tmp = vminf(array[17], array[25]); + array[25] = vmaxf(array[17], array[25]); + array[17] = tmp; + tmp = vminf(array[18], array[26]); + array[26] = vmaxf(array[18], array[26]); + array[18] = tmp; + tmp = vminf(array[19], array[27]); + array[27] = vmaxf(array[19], array[27]); + array[19] = tmp; + tmp = vminf(array[20], array[28]); + array[28] = vmaxf(array[20], array[28]); + array[20] = tmp; + tmp = vminf(array[21], array[29]); + array[29] = vmaxf(array[21], array[29]); + array[21] = tmp; + tmp = vminf(array[22], array[30]); + array[30] = vmaxf(array[22], array[30]); + array[22] = tmp; + tmp = vminf(array[23], array[31]); + array[31] = vmaxf(array[23], array[31]); + array[23] = tmp; + tmp = vminf(array[32], array[40]); + array[40] = vmaxf(array[32], array[40]); + array[32] = tmp; + tmp = vminf(array[33], array[41]); + array[41] = vmaxf(array[33], array[41]); + array[33] = tmp; + tmp = vminf(array[34], array[42]); + array[42] = vmaxf(array[34], array[42]); + array[34] = tmp; + tmp = vminf(array[35], array[43]); + array[43] = vmaxf(array[35], array[43]); + array[35] = tmp; + tmp = vminf(array[36], array[44]); + array[44] = vmaxf(array[36], array[44]); + array[36] = tmp; + tmp = vminf(array[37], array[45]); + array[45] = vmaxf(array[37], array[45]); + array[37] = tmp; + tmp = vminf(array[38], array[46]); + array[46] = vmaxf(array[38], array[46]); + array[38] = tmp; + tmp = vminf(array[39], array[47]); + array[47] = vmaxf(array[39], array[47]); + array[39] = tmp; + tmp = vminf(array[8], array[32]); + array[32] = vmaxf(array[8], array[32]); + array[8] = tmp; + tmp = vminf(array[9], array[33]); + array[33] = vmaxf(array[9], array[33]); + array[9] = tmp; + tmp = vminf(array[10], array[34]); + array[34] = vmaxf(array[10], array[34]); + array[10] = tmp; + tmp = vminf(array[11], array[35]); + array[35] = vmaxf(array[11], array[35]); + array[11] = tmp; + tmp = vminf(array[12], array[36]); + array[36] = vmaxf(array[12], array[36]); + array[12] = tmp; + tmp = vminf(array[13], array[37]); + array[37] = vmaxf(array[13], array[37]); + array[13] = tmp; + tmp = vminf(array[14], array[38]); + array[38] = vmaxf(array[14], array[38]); + array[14] = tmp; + tmp = vminf(array[15], array[39]); + array[39] = vmaxf(array[15], array[39]); + array[15] = tmp; + tmp = vminf(array[24], array[48]); + array[48] = vmaxf(array[24], array[48]); + array[24] = tmp; + tmp = vminf(array[8], array[16]); + array[16] = vmaxf(array[8], array[16]); + array[8] = tmp; + tmp = vminf(array[9], array[17]); + array[17] = vmaxf(array[9], array[17]); + array[9] = tmp; + tmp = vminf(array[10], array[18]); + array[18] = vmaxf(array[10], array[18]); + array[10] = tmp; + tmp = vminf(array[11], array[19]); + array[19] = vmaxf(array[11], array[19]); + array[11] = tmp; + tmp = vminf(array[12], array[20]); + array[20] = vmaxf(array[12], array[20]); + array[12] = tmp; + tmp = vminf(array[13], array[21]); + array[21] = vmaxf(array[13], array[21]); + array[13] = tmp; + tmp = vminf(array[14], array[22]); + array[22] = vmaxf(array[14], array[22]); + array[14] = tmp; + tmp = vminf(array[15], array[23]); + array[23] = vmaxf(array[15], array[23]); + array[15] = tmp; + tmp = vminf(array[24], array[32]); + array[32] = vmaxf(array[24], array[32]); + array[24] = tmp; + tmp = vminf(array[25], array[33]); + array[33] = vmaxf(array[25], array[33]); + array[25] = tmp; + tmp = vminf(array[26], array[34]); + array[34] = vmaxf(array[26], array[34]); + array[26] = tmp; + tmp = vminf(array[27], array[35]); + array[35] = vmaxf(array[27], array[35]); + array[27] = tmp; + tmp = vminf(array[28], array[36]); + array[36] = vmaxf(array[28], array[36]); + array[28] = tmp; + tmp = vminf(array[29], array[37]); + array[37] = vmaxf(array[29], array[37]); + array[29] = tmp; + tmp = vminf(array[30], array[38]); + array[38] = vmaxf(array[30], array[38]); + array[30] = tmp; + tmp = vminf(array[31], array[39]); + array[39] = vmaxf(array[31], array[39]); + array[31] = tmp; + tmp = vminf(array[40], array[48]); + array[48] = vmaxf(array[40], array[48]); + array[40] = tmp; + tmp = vminf(array[0], array[4]); + array[4] = vmaxf(array[0], array[4]); + array[0] = tmp; + tmp = vminf(array[1], array[5]); + array[5] = vmaxf(array[1], array[5]); + array[1] = tmp; + tmp = vminf(array[2], array[6]); + array[6] = vmaxf(array[2], array[6]); + array[2] = tmp; + tmp = vminf(array[3], array[7]); + array[7] = vmaxf(array[3], array[7]); + array[3] = tmp; + tmp = vminf(array[8], array[12]); + array[12] = vmaxf(array[8], array[12]); + array[8] = tmp; + tmp = vminf(array[9], array[13]); + array[13] = vmaxf(array[9], array[13]); + array[9] = tmp; + tmp = vminf(array[10], array[14]); + array[14] = vmaxf(array[10], array[14]); + array[10] = tmp; + tmp = vminf(array[11], array[15]); + array[15] = vmaxf(array[11], array[15]); + array[11] = tmp; + tmp = vminf(array[16], array[20]); + array[20] = vmaxf(array[16], array[20]); + array[16] = tmp; + tmp = vminf(array[17], array[21]); + array[21] = vmaxf(array[17], array[21]); + array[17] = tmp; + tmp = vminf(array[18], array[22]); + array[22] = vmaxf(array[18], array[22]); + array[18] = tmp; + tmp = vminf(array[19], array[23]); + array[23] = vmaxf(array[19], array[23]); + array[19] = tmp; + tmp = vminf(array[24], array[28]); + array[28] = vmaxf(array[24], array[28]); + array[24] = tmp; + tmp = vminf(array[25], array[29]); + array[29] = vmaxf(array[25], array[29]); + array[25] = tmp; + tmp = vminf(array[26], array[30]); + array[30] = vmaxf(array[26], array[30]); + array[26] = tmp; + tmp = vminf(array[27], array[31]); + array[31] = vmaxf(array[27], array[31]); + array[27] = tmp; + tmp = vminf(array[32], array[36]); + array[36] = vmaxf(array[32], array[36]); + array[32] = tmp; + tmp = vminf(array[33], array[37]); + array[37] = vmaxf(array[33], array[37]); + array[33] = tmp; + tmp = vminf(array[34], array[38]); + array[38] = vmaxf(array[34], array[38]); + array[34] = tmp; + tmp = vminf(array[35], array[39]); + array[39] = vmaxf(array[35], array[39]); + array[35] = tmp; + tmp = vminf(array[40], array[44]); + array[44] = vmaxf(array[40], array[44]); + array[40] = tmp; + tmp = vminf(array[41], array[45]); + array[45] = vmaxf(array[41], array[45]); + array[41] = tmp; + tmp = vminf(array[42], array[46]); + array[46] = vmaxf(array[42], array[46]); + array[42] = tmp; + tmp = vminf(array[43], array[47]); + array[47] = vmaxf(array[43], array[47]); + array[43] = tmp; + tmp = vminf(array[4], array[32]); + array[32] = vmaxf(array[4], array[32]); + array[4] = tmp; + tmp = vminf(array[5], array[33]); + array[33] = vmaxf(array[5], array[33]); + array[5] = tmp; + tmp = vminf(array[6], array[34]); + array[34] = vmaxf(array[6], array[34]); + array[6] = tmp; + tmp = vminf(array[7], array[35]); + array[35] = vmaxf(array[7], array[35]); + array[7] = tmp; + tmp = vminf(array[12], array[40]); + array[40] = vmaxf(array[12], array[40]); + array[12] = tmp; + tmp = vminf(array[13], array[41]); + array[41] = vmaxf(array[13], array[41]); + array[13] = tmp; + tmp = vminf(array[14], array[42]); + array[42] = vmaxf(array[14], array[42]); + array[14] = tmp; + tmp = vminf(array[15], array[43]); + array[43] = vmaxf(array[15], array[43]); + array[15] = tmp; + tmp = vminf(array[20], array[48]); + array[48] = vmaxf(array[20], array[48]); + array[20] = tmp; + tmp = vminf(array[4], array[16]); + array[16] = vmaxf(array[4], array[16]); + array[4] = tmp; + tmp = vminf(array[5], array[17]); + array[17] = vmaxf(array[5], array[17]); + array[5] = tmp; + tmp = vminf(array[6], array[18]); + array[18] = vmaxf(array[6], array[18]); + array[6] = tmp; + tmp = vminf(array[7], array[19]); + array[19] = vmaxf(array[7], array[19]); + array[7] = tmp; + tmp = vminf(array[12], array[24]); + array[24] = vmaxf(array[12], array[24]); + array[12] = tmp; + tmp = vminf(array[13], array[25]); + array[25] = vmaxf(array[13], array[25]); + array[13] = tmp; + tmp = vminf(array[14], array[26]); + array[26] = vmaxf(array[14], array[26]); + array[14] = tmp; + tmp = vminf(array[15], array[27]); + array[27] = vmaxf(array[15], array[27]); + array[15] = tmp; + tmp = vminf(array[20], array[32]); + array[32] = vmaxf(array[20], array[32]); + array[20] = tmp; + tmp = vminf(array[21], array[33]); + array[33] = vmaxf(array[21], array[33]); + array[21] = tmp; + tmp = vminf(array[22], array[34]); + array[34] = vmaxf(array[22], array[34]); + array[22] = tmp; + tmp = vminf(array[23], array[35]); + array[35] = vmaxf(array[23], array[35]); + array[23] = tmp; + tmp = vminf(array[28], array[40]); + array[40] = vmaxf(array[28], array[40]); + array[28] = tmp; + tmp = vminf(array[29], array[41]); + array[41] = vmaxf(array[29], array[41]); + array[29] = tmp; + tmp = vminf(array[30], array[42]); + array[42] = vmaxf(array[30], array[42]); + array[30] = tmp; + tmp = vminf(array[31], array[43]); + array[43] = vmaxf(array[31], array[43]); + array[31] = tmp; + tmp = vminf(array[36], array[48]); + array[48] = vmaxf(array[36], array[48]); + array[36] = tmp; + tmp = vminf(array[4], array[8]); + array[8] = vmaxf(array[4], array[8]); + array[4] = tmp; + tmp = vminf(array[5], array[9]); + array[9] = vmaxf(array[5], array[9]); + array[5] = tmp; + tmp = vminf(array[6], array[10]); + array[10] = vmaxf(array[6], array[10]); + array[6] = tmp; + tmp = vminf(array[7], array[11]); + array[11] = vmaxf(array[7], array[11]); + array[7] = tmp; + tmp = vminf(array[12], array[16]); + array[16] = vmaxf(array[12], array[16]); + array[12] = tmp; + tmp = vminf(array[13], array[17]); + array[17] = vmaxf(array[13], array[17]); + array[13] = tmp; + tmp = vminf(array[14], array[18]); + array[18] = vmaxf(array[14], array[18]); + array[14] = tmp; + tmp = vminf(array[15], array[19]); + array[19] = vmaxf(array[15], array[19]); + array[15] = tmp; + tmp = vminf(array[20], array[24]); + array[24] = vmaxf(array[20], array[24]); + array[20] = tmp; + tmp = vminf(array[21], array[25]); + array[25] = vmaxf(array[21], array[25]); + array[21] = tmp; + tmp = vminf(array[22], array[26]); + array[26] = vmaxf(array[22], array[26]); + array[22] = tmp; + tmp = vminf(array[23], array[27]); + array[27] = vmaxf(array[23], array[27]); + array[23] = tmp; + tmp = vminf(array[28], array[32]); + array[32] = vmaxf(array[28], array[32]); + array[28] = tmp; + tmp = vminf(array[29], array[33]); + array[33] = vmaxf(array[29], array[33]); + array[29] = tmp; + tmp = vminf(array[30], array[34]); + array[34] = vmaxf(array[30], array[34]); + array[30] = tmp; + tmp = vminf(array[31], array[35]); + array[35] = vmaxf(array[31], array[35]); + array[31] = tmp; + tmp = vminf(array[36], array[40]); + array[40] = vmaxf(array[36], array[40]); + array[36] = tmp; + tmp = vminf(array[37], array[41]); + array[41] = vmaxf(array[37], array[41]); + array[37] = tmp; + tmp = vminf(array[38], array[42]); + array[42] = vmaxf(array[38], array[42]); + array[38] = tmp; + tmp = vminf(array[39], array[43]); + array[43] = vmaxf(array[39], array[43]); + array[39] = tmp; + tmp = vminf(array[44], array[48]); + array[48] = vmaxf(array[44], array[48]); + array[44] = tmp; + tmp = vminf(array[0], array[2]); + array[2] = vmaxf(array[0], array[2]); + array[0] = tmp; + tmp = vminf(array[1], array[3]); + array[3] = vmaxf(array[1], array[3]); + array[1] = tmp; + tmp = vminf(array[4], array[6]); + array[6] = vmaxf(array[4], array[6]); + array[4] = tmp; + tmp = vminf(array[5], array[7]); + array[7] = vmaxf(array[5], array[7]); + array[5] = tmp; + tmp = vminf(array[8], array[10]); + array[10] = vmaxf(array[8], array[10]); + array[8] = tmp; + tmp = vminf(array[9], array[11]); + array[11] = vmaxf(array[9], array[11]); + array[9] = tmp; + tmp = vminf(array[12], array[14]); + array[14] = vmaxf(array[12], array[14]); + array[12] = tmp; + tmp = vminf(array[13], array[15]); + array[15] = vmaxf(array[13], array[15]); + array[13] = tmp; + tmp = vminf(array[16], array[18]); + array[18] = vmaxf(array[16], array[18]); + array[16] = tmp; + tmp = vminf(array[17], array[19]); + array[19] = vmaxf(array[17], array[19]); + array[17] = tmp; + tmp = vminf(array[20], array[22]); + array[22] = vmaxf(array[20], array[22]); + array[20] = tmp; + tmp = vminf(array[21], array[23]); + array[23] = vmaxf(array[21], array[23]); + array[21] = tmp; + tmp = vminf(array[24], array[26]); + array[26] = vmaxf(array[24], array[26]); + array[24] = tmp; + tmp = vminf(array[25], array[27]); + array[27] = vmaxf(array[25], array[27]); + array[25] = tmp; + tmp = vminf(array[28], array[30]); + array[30] = vmaxf(array[28], array[30]); + array[28] = tmp; + tmp = vminf(array[29], array[31]); + array[31] = vmaxf(array[29], array[31]); + array[29] = tmp; + tmp = vminf(array[32], array[34]); + array[34] = vmaxf(array[32], array[34]); + array[32] = tmp; + tmp = vminf(array[33], array[35]); + array[35] = vmaxf(array[33], array[35]); + array[33] = tmp; + tmp = vminf(array[36], array[38]); + array[38] = vmaxf(array[36], array[38]); + array[36] = tmp; + tmp = vminf(array[37], array[39]); + array[39] = vmaxf(array[37], array[39]); + array[37] = tmp; + tmp = vminf(array[40], array[42]); + array[42] = vmaxf(array[40], array[42]); + array[40] = tmp; + tmp = vminf(array[41], array[43]); + array[43] = vmaxf(array[41], array[43]); + array[41] = tmp; + tmp = vminf(array[44], array[46]); + array[46] = vmaxf(array[44], array[46]); + array[44] = tmp; + tmp = vminf(array[45], array[47]); + array[47] = vmaxf(array[45], array[47]); + array[45] = tmp; + tmp = vminf(array[2], array[32]); + array[32] = vmaxf(array[2], array[32]); + array[2] = tmp; + tmp = vminf(array[3], array[33]); + array[33] = vmaxf(array[3], array[33]); + array[3] = tmp; + tmp = vminf(array[6], array[36]); + array[36] = vmaxf(array[6], array[36]); + array[6] = tmp; + tmp = vminf(array[7], array[37]); + array[37] = vmaxf(array[7], array[37]); + array[7] = tmp; + tmp = vminf(array[10], array[40]); + array[40] = vmaxf(array[10], array[40]); + array[10] = tmp; + tmp = vminf(array[11], array[41]); + array[41] = vmaxf(array[11], array[41]); + array[11] = tmp; + tmp = vminf(array[14], array[44]); + array[44] = vmaxf(array[14], array[44]); + array[14] = tmp; + tmp = vminf(array[15], array[45]); + array[45] = vmaxf(array[15], array[45]); + array[15] = tmp; + tmp = vminf(array[18], array[48]); + array[48] = vmaxf(array[18], array[48]); + array[18] = tmp; + tmp = vminf(array[2], array[16]); + array[16] = vmaxf(array[2], array[16]); + array[2] = tmp; + tmp = vminf(array[3], array[17]); + array[17] = vmaxf(array[3], array[17]); + array[3] = tmp; + tmp = vminf(array[6], array[20]); + array[20] = vmaxf(array[6], array[20]); + array[6] = tmp; + tmp = vminf(array[7], array[21]); + array[21] = vmaxf(array[7], array[21]); + array[7] = tmp; + tmp = vminf(array[10], array[24]); + array[24] = vmaxf(array[10], array[24]); + array[10] = tmp; + tmp = vminf(array[11], array[25]); + array[25] = vmaxf(array[11], array[25]); + array[11] = tmp; + tmp = vminf(array[14], array[28]); + array[28] = vmaxf(array[14], array[28]); + array[14] = tmp; + tmp = vminf(array[15], array[29]); + array[29] = vmaxf(array[15], array[29]); + array[15] = tmp; + tmp = vminf(array[18], array[32]); + array[32] = vmaxf(array[18], array[32]); + array[18] = tmp; + tmp = vminf(array[19], array[33]); + array[33] = vmaxf(array[19], array[33]); + array[19] = tmp; + tmp = vminf(array[22], array[36]); + array[36] = vmaxf(array[22], array[36]); + array[22] = tmp; + tmp = vminf(array[23], array[37]); + array[37] = vmaxf(array[23], array[37]); + array[23] = tmp; + tmp = vminf(array[26], array[40]); + array[40] = vmaxf(array[26], array[40]); + array[26] = tmp; + tmp = vminf(array[27], array[41]); + array[41] = vmaxf(array[27], array[41]); + array[27] = tmp; + tmp = vminf(array[30], array[44]); + array[44] = vmaxf(array[30], array[44]); + array[30] = tmp; + tmp = vminf(array[31], array[45]); + array[45] = vmaxf(array[31], array[45]); + array[31] = tmp; + tmp = vminf(array[34], array[48]); + array[48] = vmaxf(array[34], array[48]); + array[34] = tmp; + tmp = vminf(array[2], array[8]); + array[8] = vmaxf(array[2], array[8]); + array[2] = tmp; + tmp = vminf(array[3], array[9]); + array[9] = vmaxf(array[3], array[9]); + array[3] = tmp; + tmp = vminf(array[6], array[12]); + array[12] = vmaxf(array[6], array[12]); + array[6] = tmp; + tmp = vminf(array[7], array[13]); + array[13] = vmaxf(array[7], array[13]); + array[7] = tmp; + tmp = vminf(array[10], array[16]); + array[16] = vmaxf(array[10], array[16]); + array[10] = tmp; + tmp = vminf(array[11], array[17]); + array[17] = vmaxf(array[11], array[17]); + array[11] = tmp; + tmp = vminf(array[14], array[20]); + array[20] = vmaxf(array[14], array[20]); + array[14] = tmp; + tmp = vminf(array[15], array[21]); + array[21] = vmaxf(array[15], array[21]); + array[15] = tmp; + tmp = vminf(array[18], array[24]); + array[24] = vmaxf(array[18], array[24]); + array[18] = tmp; + tmp = vminf(array[19], array[25]); + array[25] = vmaxf(array[19], array[25]); + array[19] = tmp; + tmp = vminf(array[22], array[28]); + array[28] = vmaxf(array[22], array[28]); + array[22] = tmp; + tmp = vminf(array[23], array[29]); + array[29] = vmaxf(array[23], array[29]); + array[23] = tmp; + tmp = vminf(array[26], array[32]); + array[32] = vmaxf(array[26], array[32]); + array[26] = tmp; + tmp = vminf(array[27], array[33]); + array[33] = vmaxf(array[27], array[33]); + array[27] = tmp; + tmp = vminf(array[30], array[36]); + array[36] = vmaxf(array[30], array[36]); + array[30] = tmp; + tmp = vminf(array[31], array[37]); + array[37] = vmaxf(array[31], array[37]); + array[31] = tmp; + tmp = vminf(array[34], array[40]); + array[40] = vmaxf(array[34], array[40]); + array[34] = tmp; + tmp = vminf(array[35], array[41]); + array[41] = vmaxf(array[35], array[41]); + array[35] = tmp; + tmp = vminf(array[38], array[44]); + array[44] = vmaxf(array[38], array[44]); + array[38] = tmp; + tmp = vminf(array[39], array[45]); + array[45] = vmaxf(array[39], array[45]); + array[39] = tmp; + tmp = vminf(array[42], array[48]); + array[48] = vmaxf(array[42], array[48]); + array[42] = tmp; + tmp = vminf(array[2], array[4]); + array[4] = vmaxf(array[2], array[4]); + array[2] = tmp; + tmp = vminf(array[3], array[5]); + array[5] = vmaxf(array[3], array[5]); + array[3] = tmp; + tmp = vminf(array[6], array[8]); + array[8] = vmaxf(array[6], array[8]); + array[6] = tmp; + tmp = vminf(array[7], array[9]); + array[9] = vmaxf(array[7], array[9]); + array[7] = tmp; + tmp = vminf(array[10], array[12]); + array[12] = vmaxf(array[10], array[12]); + array[10] = tmp; + tmp = vminf(array[11], array[13]); + array[13] = vmaxf(array[11], array[13]); + array[11] = tmp; + tmp = vminf(array[14], array[16]); + array[16] = vmaxf(array[14], array[16]); + array[14] = tmp; + tmp = vminf(array[15], array[17]); + array[17] = vmaxf(array[15], array[17]); + array[15] = tmp; + tmp = vminf(array[18], array[20]); + array[20] = vmaxf(array[18], array[20]); + array[18] = tmp; + tmp = vminf(array[19], array[21]); + array[21] = vmaxf(array[19], array[21]); + array[19] = tmp; + tmp = vminf(array[22], array[24]); + array[24] = vmaxf(array[22], array[24]); + array[22] = tmp; + tmp = vminf(array[23], array[25]); + array[25] = vmaxf(array[23], array[25]); + array[23] = tmp; + tmp = vminf(array[26], array[28]); + array[28] = vmaxf(array[26], array[28]); + array[26] = tmp; + tmp = vminf(array[27], array[29]); + array[29] = vmaxf(array[27], array[29]); + array[27] = tmp; + tmp = vminf(array[30], array[32]); + array[32] = vmaxf(array[30], array[32]); + array[30] = tmp; + tmp = vminf(array[31], array[33]); + array[33] = vmaxf(array[31], array[33]); + array[31] = tmp; + tmp = vminf(array[34], array[36]); + array[36] = vmaxf(array[34], array[36]); + array[34] = tmp; + tmp = vminf(array[35], array[37]); + array[37] = vmaxf(array[35], array[37]); + array[35] = tmp; + tmp = vminf(array[38], array[40]); + array[40] = vmaxf(array[38], array[40]); + array[38] = tmp; + tmp = vminf(array[39], array[41]); + array[41] = vmaxf(array[39], array[41]); + array[39] = tmp; + tmp = vminf(array[42], array[44]); + array[44] = vmaxf(array[42], array[44]); + array[42] = tmp; + tmp = vminf(array[43], array[45]); + array[45] = vmaxf(array[43], array[45]); + array[43] = tmp; + tmp = vminf(array[46], array[48]); + array[48] = vmaxf(array[46], array[48]); + array[46] = tmp; + array[1] = vmaxf(array[0], array[1]); + array[3] = vmaxf(array[2], array[3]); + array[5] = vmaxf(array[4], array[5]); + array[7] = vmaxf(array[6], array[7]); + array[9] = vmaxf(array[8], array[9]); + array[11] = vmaxf(array[10], array[11]); + array[13] = vmaxf(array[12], array[13]); + array[15] = vmaxf(array[14], array[15]); + array[17] = vmaxf(array[16], array[17]); + array[19] = vmaxf(array[18], array[19]); + array[21] = vmaxf(array[20], array[21]); + array[23] = vmaxf(array[22], array[23]); + array[24] = vminf(array[24], array[25]); + array[26] = vminf(array[26], array[27]); + array[28] = vminf(array[28], array[29]); + array[30] = vminf(array[30], array[31]); + array[32] = vminf(array[32], array[33]); + array[34] = vminf(array[34], array[35]); + array[36] = vminf(array[36], array[37]); + array[38] = vminf(array[38], array[39]); + array[40] = vminf(array[40], array[41]); + array[42] = vminf(array[42], array[43]); + array[44] = vminf(array[44], array[45]); + array[46] = vminf(array[46], array[47]); + array[32] = vmaxf(array[1], array[32]); + array[34] = vmaxf(array[3], array[34]); + array[36] = vmaxf(array[5], array[36]); + array[38] = vmaxf(array[7], array[38]); + array[9] = vminf(array[9], array[40]); + array[11] = vminf(array[11], array[42]); + array[13] = vminf(array[13], array[44]); + array[15] = vminf(array[15], array[46]); + array[17] = vminf(array[17], array[48]); + array[24] = vmaxf(array[9], array[24]); + array[26] = vmaxf(array[11], array[26]); + array[28] = vmaxf(array[13], array[28]); + array[30] = vmaxf(array[15], array[30]); + array[17] = vminf(array[17], array[32]); + array[19] = vminf(array[19], array[34]); + array[21] = vminf(array[21], array[36]); + array[23] = vminf(array[23], array[38]); + array[24] = vmaxf(array[17], array[24]); + array[26] = vmaxf(array[19], array[26]); + array[21] = vminf(array[21], array[28]); + array[23] = vminf(array[23], array[30]); + array[24] = vmaxf(array[21], array[24]); + array[23] = vminf(array[23], array[26]); + return vmaxf(array[23], array[24]); +} +#endif + +template +inline T median(std::array array) +{ + T tmp = std::min(array[0], array[64]); + array[64] = std::max(array[0], array[64]); + array[0] = tmp; + tmp = std::min(array[1], array[65]); + array[65] = std::max(array[1], array[65]); + array[1] = tmp; + tmp = std::min(array[2], array[66]); + array[66] = std::max(array[2], array[66]); + array[2] = tmp; + tmp = std::min(array[3], array[67]); + array[67] = std::max(array[3], array[67]); + array[3] = tmp; + tmp = std::min(array[4], array[68]); + array[68] = std::max(array[4], array[68]); + array[4] = tmp; + tmp = std::min(array[5], array[69]); + array[69] = std::max(array[5], array[69]); + array[5] = tmp; + tmp = std::min(array[6], array[70]); + array[70] = std::max(array[6], array[70]); + array[6] = tmp; + tmp = std::min(array[7], array[71]); + array[71] = std::max(array[7], array[71]); + array[7] = tmp; + tmp = std::min(array[8], array[72]); + array[72] = std::max(array[8], array[72]); + array[8] = tmp; + tmp = std::min(array[9], array[73]); + array[73] = std::max(array[9], array[73]); + array[9] = tmp; + tmp = std::min(array[10], array[74]); + array[74] = std::max(array[10], array[74]); + array[10] = tmp; + tmp = std::min(array[11], array[75]); + array[75] = std::max(array[11], array[75]); + array[11] = tmp; + tmp = std::min(array[12], array[76]); + array[76] = std::max(array[12], array[76]); + array[12] = tmp; + tmp = std::min(array[13], array[77]); + array[77] = std::max(array[13], array[77]); + array[13] = tmp; + tmp = std::min(array[14], array[78]); + array[78] = std::max(array[14], array[78]); + array[14] = tmp; + tmp = std::min(array[15], array[79]); + array[79] = std::max(array[15], array[79]); + array[15] = tmp; + tmp = std::min(array[16], array[80]); + array[80] = std::max(array[16], array[80]); + array[16] = tmp; + tmp = std::min(array[0], array[32]); + array[32] = std::max(array[0], array[32]); + array[0] = tmp; + tmp = std::min(array[1], array[33]); + array[33] = std::max(array[1], array[33]); + array[1] = tmp; + tmp = std::min(array[2], array[34]); + array[34] = std::max(array[2], array[34]); + array[2] = tmp; + tmp = std::min(array[3], array[35]); + array[35] = std::max(array[3], array[35]); + array[3] = tmp; + tmp = std::min(array[4], array[36]); + array[36] = std::max(array[4], array[36]); + array[4] = tmp; + tmp = std::min(array[5], array[37]); + array[37] = std::max(array[5], array[37]); + array[5] = tmp; + tmp = std::min(array[6], array[38]); + array[38] = std::max(array[6], array[38]); + array[6] = tmp; + tmp = std::min(array[7], array[39]); + array[39] = std::max(array[7], array[39]); + array[7] = tmp; + tmp = std::min(array[8], array[40]); + array[40] = std::max(array[8], array[40]); + array[8] = tmp; + tmp = std::min(array[9], array[41]); + array[41] = std::max(array[9], array[41]); + array[9] = tmp; + tmp = std::min(array[10], array[42]); + array[42] = std::max(array[10], array[42]); + array[10] = tmp; + tmp = std::min(array[11], array[43]); + array[43] = std::max(array[11], array[43]); + array[11] = tmp; + tmp = std::min(array[12], array[44]); + array[44] = std::max(array[12], array[44]); + array[12] = tmp; + tmp = std::min(array[13], array[45]); + array[45] = std::max(array[13], array[45]); + array[13] = tmp; + tmp = std::min(array[14], array[46]); + array[46] = std::max(array[14], array[46]); + array[14] = tmp; + tmp = std::min(array[15], array[47]); + array[47] = std::max(array[15], array[47]); + array[15] = tmp; + tmp = std::min(array[16], array[48]); + array[48] = std::max(array[16], array[48]); + array[16] = tmp; + tmp = std::min(array[17], array[49]); + array[49] = std::max(array[17], array[49]); + array[17] = tmp; + tmp = std::min(array[18], array[50]); + array[50] = std::max(array[18], array[50]); + array[18] = tmp; + tmp = std::min(array[19], array[51]); + array[51] = std::max(array[19], array[51]); + array[19] = tmp; + tmp = std::min(array[20], array[52]); + array[52] = std::max(array[20], array[52]); + array[20] = tmp; + tmp = std::min(array[21], array[53]); + array[53] = std::max(array[21], array[53]); + array[21] = tmp; + tmp = std::min(array[22], array[54]); + array[54] = std::max(array[22], array[54]); + array[22] = tmp; + tmp = std::min(array[23], array[55]); + array[55] = std::max(array[23], array[55]); + array[23] = tmp; + tmp = std::min(array[24], array[56]); + array[56] = std::max(array[24], array[56]); + array[24] = tmp; + tmp = std::min(array[25], array[57]); + array[57] = std::max(array[25], array[57]); + array[25] = tmp; + tmp = std::min(array[26], array[58]); + array[58] = std::max(array[26], array[58]); + array[26] = tmp; + tmp = std::min(array[27], array[59]); + array[59] = std::max(array[27], array[59]); + array[27] = tmp; + tmp = std::min(array[28], array[60]); + array[60] = std::max(array[28], array[60]); + array[28] = tmp; + tmp = std::min(array[29], array[61]); + array[61] = std::max(array[29], array[61]); + array[29] = tmp; + tmp = std::min(array[30], array[62]); + array[62] = std::max(array[30], array[62]); + array[30] = tmp; + tmp = std::min(array[31], array[63]); + array[63] = std::max(array[31], array[63]); + array[31] = tmp; + tmp = std::min(array[32], array[64]); + array[64] = std::max(array[32], array[64]); + array[32] = tmp; + tmp = std::min(array[33], array[65]); + array[65] = std::max(array[33], array[65]); + array[33] = tmp; + tmp = std::min(array[34], array[66]); + array[66] = std::max(array[34], array[66]); + array[34] = tmp; + tmp = std::min(array[35], array[67]); + array[67] = std::max(array[35], array[67]); + array[35] = tmp; + tmp = std::min(array[36], array[68]); + array[68] = std::max(array[36], array[68]); + array[36] = tmp; + tmp = std::min(array[37], array[69]); + array[69] = std::max(array[37], array[69]); + array[37] = tmp; + tmp = std::min(array[38], array[70]); + array[70] = std::max(array[38], array[70]); + array[38] = tmp; + tmp = std::min(array[39], array[71]); + array[71] = std::max(array[39], array[71]); + array[39] = tmp; + tmp = std::min(array[40], array[72]); + array[72] = std::max(array[40], array[72]); + array[40] = tmp; + tmp = std::min(array[41], array[73]); + array[73] = std::max(array[41], array[73]); + array[41] = tmp; + tmp = std::min(array[42], array[74]); + array[74] = std::max(array[42], array[74]); + array[42] = tmp; + tmp = std::min(array[43], array[75]); + array[75] = std::max(array[43], array[75]); + array[43] = tmp; + tmp = std::min(array[44], array[76]); + array[76] = std::max(array[44], array[76]); + array[44] = tmp; + tmp = std::min(array[45], array[77]); + array[77] = std::max(array[45], array[77]); + array[45] = tmp; + tmp = std::min(array[46], array[78]); + array[78] = std::max(array[46], array[78]); + array[46] = tmp; + tmp = std::min(array[47], array[79]); + array[79] = std::max(array[47], array[79]); + array[47] = tmp; + tmp = std::min(array[48], array[80]); + array[80] = std::max(array[48], array[80]); + array[48] = tmp; + tmp = std::min(array[0], array[16]); + array[16] = std::max(array[0], array[16]); + array[0] = tmp; + tmp = std::min(array[1], array[17]); + array[17] = std::max(array[1], array[17]); + array[1] = tmp; + tmp = std::min(array[2], array[18]); + array[18] = std::max(array[2], array[18]); + array[2] = tmp; + tmp = std::min(array[3], array[19]); + array[19] = std::max(array[3], array[19]); + array[3] = tmp; + tmp = std::min(array[4], array[20]); + array[20] = std::max(array[4], array[20]); + array[4] = tmp; + tmp = std::min(array[5], array[21]); + array[21] = std::max(array[5], array[21]); + array[5] = tmp; + tmp = std::min(array[6], array[22]); + array[22] = std::max(array[6], array[22]); + array[6] = tmp; + tmp = std::min(array[7], array[23]); + array[23] = std::max(array[7], array[23]); + array[7] = tmp; + tmp = std::min(array[8], array[24]); + array[24] = std::max(array[8], array[24]); + array[8] = tmp; + tmp = std::min(array[9], array[25]); + array[25] = std::max(array[9], array[25]); + array[9] = tmp; + tmp = std::min(array[10], array[26]); + array[26] = std::max(array[10], array[26]); + array[10] = tmp; + tmp = std::min(array[11], array[27]); + array[27] = std::max(array[11], array[27]); + array[11] = tmp; + tmp = std::min(array[12], array[28]); + array[28] = std::max(array[12], array[28]); + array[12] = tmp; + tmp = std::min(array[13], array[29]); + array[29] = std::max(array[13], array[29]); + array[13] = tmp; + tmp = std::min(array[14], array[30]); + array[30] = std::max(array[14], array[30]); + array[14] = tmp; + tmp = std::min(array[15], array[31]); + array[31] = std::max(array[15], array[31]); + array[15] = tmp; + tmp = std::min(array[32], array[48]); + array[48] = std::max(array[32], array[48]); + array[32] = tmp; + tmp = std::min(array[33], array[49]); + array[49] = std::max(array[33], array[49]); + array[33] = tmp; + tmp = std::min(array[34], array[50]); + array[50] = std::max(array[34], array[50]); + array[34] = tmp; + tmp = std::min(array[35], array[51]); + array[51] = std::max(array[35], array[51]); + array[35] = tmp; + tmp = std::min(array[36], array[52]); + array[52] = std::max(array[36], array[52]); + array[36] = tmp; + tmp = std::min(array[37], array[53]); + array[53] = std::max(array[37], array[53]); + array[37] = tmp; + tmp = std::min(array[38], array[54]); + array[54] = std::max(array[38], array[54]); + array[38] = tmp; + tmp = std::min(array[39], array[55]); + array[55] = std::max(array[39], array[55]); + array[39] = tmp; + tmp = std::min(array[40], array[56]); + array[56] = std::max(array[40], array[56]); + array[40] = tmp; + tmp = std::min(array[41], array[57]); + array[57] = std::max(array[41], array[57]); + array[41] = tmp; + tmp = std::min(array[42], array[58]); + array[58] = std::max(array[42], array[58]); + array[42] = tmp; + tmp = std::min(array[43], array[59]); + array[59] = std::max(array[43], array[59]); + array[43] = tmp; + tmp = std::min(array[44], array[60]); + array[60] = std::max(array[44], array[60]); + array[44] = tmp; + tmp = std::min(array[45], array[61]); + array[61] = std::max(array[45], array[61]); + array[45] = tmp; + tmp = std::min(array[46], array[62]); + array[62] = std::max(array[46], array[62]); + array[46] = tmp; + tmp = std::min(array[47], array[63]); + array[63] = std::max(array[47], array[63]); + array[47] = tmp; + tmp = std::min(array[64], array[80]); + array[80] = std::max(array[64], array[80]); + array[64] = tmp; + tmp = std::min(array[16], array[64]); + array[64] = std::max(array[16], array[64]); + array[16] = tmp; + tmp = std::min(array[17], array[65]); + array[65] = std::max(array[17], array[65]); + array[17] = tmp; + tmp = std::min(array[18], array[66]); + array[66] = std::max(array[18], array[66]); + array[18] = tmp; + tmp = std::min(array[19], array[67]); + array[67] = std::max(array[19], array[67]); + array[19] = tmp; + tmp = std::min(array[20], array[68]); + array[68] = std::max(array[20], array[68]); + array[20] = tmp; + tmp = std::min(array[21], array[69]); + array[69] = std::max(array[21], array[69]); + array[21] = tmp; + tmp = std::min(array[22], array[70]); + array[70] = std::max(array[22], array[70]); + array[22] = tmp; + tmp = std::min(array[23], array[71]); + array[71] = std::max(array[23], array[71]); + array[23] = tmp; + tmp = std::min(array[24], array[72]); + array[72] = std::max(array[24], array[72]); + array[24] = tmp; + tmp = std::min(array[25], array[73]); + array[73] = std::max(array[25], array[73]); + array[25] = tmp; + tmp = std::min(array[26], array[74]); + array[74] = std::max(array[26], array[74]); + array[26] = tmp; + tmp = std::min(array[27], array[75]); + array[75] = std::max(array[27], array[75]); + array[27] = tmp; + tmp = std::min(array[28], array[76]); + array[76] = std::max(array[28], array[76]); + array[28] = tmp; + tmp = std::min(array[29], array[77]); + array[77] = std::max(array[29], array[77]); + array[29] = tmp; + tmp = std::min(array[30], array[78]); + array[78] = std::max(array[30], array[78]); + array[30] = tmp; + tmp = std::min(array[31], array[79]); + array[79] = std::max(array[31], array[79]); + array[31] = tmp; + tmp = std::min(array[16], array[32]); + array[32] = std::max(array[16], array[32]); + array[16] = tmp; + tmp = std::min(array[17], array[33]); + array[33] = std::max(array[17], array[33]); + array[17] = tmp; + tmp = std::min(array[18], array[34]); + array[34] = std::max(array[18], array[34]); + array[18] = tmp; + tmp = std::min(array[19], array[35]); + array[35] = std::max(array[19], array[35]); + array[19] = tmp; + tmp = std::min(array[20], array[36]); + array[36] = std::max(array[20], array[36]); + array[20] = tmp; + tmp = std::min(array[21], array[37]); + array[37] = std::max(array[21], array[37]); + array[21] = tmp; + tmp = std::min(array[22], array[38]); + array[38] = std::max(array[22], array[38]); + array[22] = tmp; + tmp = std::min(array[23], array[39]); + array[39] = std::max(array[23], array[39]); + array[23] = tmp; + tmp = std::min(array[24], array[40]); + array[40] = std::max(array[24], array[40]); + array[24] = tmp; + tmp = std::min(array[25], array[41]); + array[41] = std::max(array[25], array[41]); + array[25] = tmp; + tmp = std::min(array[26], array[42]); + array[42] = std::max(array[26], array[42]); + array[26] = tmp; + tmp = std::min(array[27], array[43]); + array[43] = std::max(array[27], array[43]); + array[27] = tmp; + tmp = std::min(array[28], array[44]); + array[44] = std::max(array[28], array[44]); + array[28] = tmp; + tmp = std::min(array[29], array[45]); + array[45] = std::max(array[29], array[45]); + array[29] = tmp; + tmp = std::min(array[30], array[46]); + array[46] = std::max(array[30], array[46]); + array[30] = tmp; + tmp = std::min(array[31], array[47]); + array[47] = std::max(array[31], array[47]); + array[31] = tmp; + tmp = std::min(array[48], array[64]); + array[64] = std::max(array[48], array[64]); + array[48] = tmp; + tmp = std::min(array[49], array[65]); + array[65] = std::max(array[49], array[65]); + array[49] = tmp; + tmp = std::min(array[50], array[66]); + array[66] = std::max(array[50], array[66]); + array[50] = tmp; + tmp = std::min(array[51], array[67]); + array[67] = std::max(array[51], array[67]); + array[51] = tmp; + tmp = std::min(array[52], array[68]); + array[68] = std::max(array[52], array[68]); + array[52] = tmp; + tmp = std::min(array[53], array[69]); + array[69] = std::max(array[53], array[69]); + array[53] = tmp; + tmp = std::min(array[54], array[70]); + array[70] = std::max(array[54], array[70]); + array[54] = tmp; + tmp = std::min(array[55], array[71]); + array[71] = std::max(array[55], array[71]); + array[55] = tmp; + tmp = std::min(array[56], array[72]); + array[72] = std::max(array[56], array[72]); + array[56] = tmp; + tmp = std::min(array[57], array[73]); + array[73] = std::max(array[57], array[73]); + array[57] = tmp; + tmp = std::min(array[58], array[74]); + array[74] = std::max(array[58], array[74]); + array[58] = tmp; + tmp = std::min(array[59], array[75]); + array[75] = std::max(array[59], array[75]); + array[59] = tmp; + tmp = std::min(array[60], array[76]); + array[76] = std::max(array[60], array[76]); + array[60] = tmp; + tmp = std::min(array[61], array[77]); + array[77] = std::max(array[61], array[77]); + array[61] = tmp; + tmp = std::min(array[62], array[78]); + array[78] = std::max(array[62], array[78]); + array[62] = tmp; + tmp = std::min(array[63], array[79]); + array[79] = std::max(array[63], array[79]); + array[63] = tmp; + tmp = std::min(array[0], array[8]); + array[8] = std::max(array[0], array[8]); + array[0] = tmp; + tmp = std::min(array[1], array[9]); + array[9] = std::max(array[1], array[9]); + array[1] = tmp; + tmp = std::min(array[2], array[10]); + array[10] = std::max(array[2], array[10]); + array[2] = tmp; + tmp = std::min(array[3], array[11]); + array[11] = std::max(array[3], array[11]); + array[3] = tmp; + tmp = std::min(array[4], array[12]); + array[12] = std::max(array[4], array[12]); + array[4] = tmp; + tmp = std::min(array[5], array[13]); + array[13] = std::max(array[5], array[13]); + array[5] = tmp; + tmp = std::min(array[6], array[14]); + array[14] = std::max(array[6], array[14]); + array[6] = tmp; + tmp = std::min(array[7], array[15]); + array[15] = std::max(array[7], array[15]); + array[7] = tmp; + tmp = std::min(array[16], array[24]); + array[24] = std::max(array[16], array[24]); + array[16] = tmp; + tmp = std::min(array[17], array[25]); + array[25] = std::max(array[17], array[25]); + array[17] = tmp; + tmp = std::min(array[18], array[26]); + array[26] = std::max(array[18], array[26]); + array[18] = tmp; + tmp = std::min(array[19], array[27]); + array[27] = std::max(array[19], array[27]); + array[19] = tmp; + tmp = std::min(array[20], array[28]); + array[28] = std::max(array[20], array[28]); + array[20] = tmp; + tmp = std::min(array[21], array[29]); + array[29] = std::max(array[21], array[29]); + array[21] = tmp; + tmp = std::min(array[22], array[30]); + array[30] = std::max(array[22], array[30]); + array[22] = tmp; + tmp = std::min(array[23], array[31]); + array[31] = std::max(array[23], array[31]); + array[23] = tmp; + tmp = std::min(array[32], array[40]); + array[40] = std::max(array[32], array[40]); + array[32] = tmp; + tmp = std::min(array[33], array[41]); + array[41] = std::max(array[33], array[41]); + array[33] = tmp; + tmp = std::min(array[34], array[42]); + array[42] = std::max(array[34], array[42]); + array[34] = tmp; + tmp = std::min(array[35], array[43]); + array[43] = std::max(array[35], array[43]); + array[35] = tmp; + tmp = std::min(array[36], array[44]); + array[44] = std::max(array[36], array[44]); + array[36] = tmp; + tmp = std::min(array[37], array[45]); + array[45] = std::max(array[37], array[45]); + array[37] = tmp; + tmp = std::min(array[38], array[46]); + array[46] = std::max(array[38], array[46]); + array[38] = tmp; + tmp = std::min(array[39], array[47]); + array[47] = std::max(array[39], array[47]); + array[39] = tmp; + tmp = std::min(array[48], array[56]); + array[56] = std::max(array[48], array[56]); + array[48] = tmp; + tmp = std::min(array[49], array[57]); + array[57] = std::max(array[49], array[57]); + array[49] = tmp; + tmp = std::min(array[50], array[58]); + array[58] = std::max(array[50], array[58]); + array[50] = tmp; + tmp = std::min(array[51], array[59]); + array[59] = std::max(array[51], array[59]); + array[51] = tmp; + tmp = std::min(array[52], array[60]); + array[60] = std::max(array[52], array[60]); + array[52] = tmp; + tmp = std::min(array[53], array[61]); + array[61] = std::max(array[53], array[61]); + array[53] = tmp; + tmp = std::min(array[54], array[62]); + array[62] = std::max(array[54], array[62]); + array[54] = tmp; + tmp = std::min(array[55], array[63]); + array[63] = std::max(array[55], array[63]); + array[55] = tmp; + tmp = std::min(array[64], array[72]); + array[72] = std::max(array[64], array[72]); + array[64] = tmp; + tmp = std::min(array[65], array[73]); + array[73] = std::max(array[65], array[73]); + array[65] = tmp; + tmp = std::min(array[66], array[74]); + array[74] = std::max(array[66], array[74]); + array[66] = tmp; + tmp = std::min(array[67], array[75]); + array[75] = std::max(array[67], array[75]); + array[67] = tmp; + tmp = std::min(array[68], array[76]); + array[76] = std::max(array[68], array[76]); + array[68] = tmp; + tmp = std::min(array[69], array[77]); + array[77] = std::max(array[69], array[77]); + array[69] = tmp; + tmp = std::min(array[70], array[78]); + array[78] = std::max(array[70], array[78]); + array[70] = tmp; + tmp = std::min(array[71], array[79]); + array[79] = std::max(array[71], array[79]); + array[71] = tmp; + tmp = std::min(array[8], array[64]); + array[64] = std::max(array[8], array[64]); + array[8] = tmp; + tmp = std::min(array[9], array[65]); + array[65] = std::max(array[9], array[65]); + array[9] = tmp; + tmp = std::min(array[10], array[66]); + array[66] = std::max(array[10], array[66]); + array[10] = tmp; + tmp = std::min(array[11], array[67]); + array[67] = std::max(array[11], array[67]); + array[11] = tmp; + tmp = std::min(array[12], array[68]); + array[68] = std::max(array[12], array[68]); + array[12] = tmp; + tmp = std::min(array[13], array[69]); + array[69] = std::max(array[13], array[69]); + array[13] = tmp; + tmp = std::min(array[14], array[70]); + array[70] = std::max(array[14], array[70]); + array[14] = tmp; + tmp = std::min(array[15], array[71]); + array[71] = std::max(array[15], array[71]); + array[15] = tmp; + tmp = std::min(array[24], array[80]); + array[80] = std::max(array[24], array[80]); + array[24] = tmp; + tmp = std::min(array[8], array[32]); + array[32] = std::max(array[8], array[32]); + array[8] = tmp; + tmp = std::min(array[9], array[33]); + array[33] = std::max(array[9], array[33]); + array[9] = tmp; + tmp = std::min(array[10], array[34]); + array[34] = std::max(array[10], array[34]); + array[10] = tmp; + tmp = std::min(array[11], array[35]); + array[35] = std::max(array[11], array[35]); + array[11] = tmp; + tmp = std::min(array[12], array[36]); + array[36] = std::max(array[12], array[36]); + array[12] = tmp; + tmp = std::min(array[13], array[37]); + array[37] = std::max(array[13], array[37]); + array[13] = tmp; + tmp = std::min(array[14], array[38]); + array[38] = std::max(array[14], array[38]); + array[14] = tmp; + tmp = std::min(array[15], array[39]); + array[39] = std::max(array[15], array[39]); + array[15] = tmp; + tmp = std::min(array[24], array[48]); + array[48] = std::max(array[24], array[48]); + array[24] = tmp; + tmp = std::min(array[25], array[49]); + array[49] = std::max(array[25], array[49]); + array[25] = tmp; + tmp = std::min(array[26], array[50]); + array[50] = std::max(array[26], array[50]); + array[26] = tmp; + tmp = std::min(array[27], array[51]); + array[51] = std::max(array[27], array[51]); + array[27] = tmp; + tmp = std::min(array[28], array[52]); + array[52] = std::max(array[28], array[52]); + array[28] = tmp; + tmp = std::min(array[29], array[53]); + array[53] = std::max(array[29], array[53]); + array[29] = tmp; + tmp = std::min(array[30], array[54]); + array[54] = std::max(array[30], array[54]); + array[30] = tmp; + tmp = std::min(array[31], array[55]); + array[55] = std::max(array[31], array[55]); + array[31] = tmp; + tmp = std::min(array[40], array[64]); + array[64] = std::max(array[40], array[64]); + array[40] = tmp; + tmp = std::min(array[41], array[65]); + array[65] = std::max(array[41], array[65]); + array[41] = tmp; + tmp = std::min(array[42], array[66]); + array[66] = std::max(array[42], array[66]); + array[42] = tmp; + tmp = std::min(array[43], array[67]); + array[67] = std::max(array[43], array[67]); + array[43] = tmp; + tmp = std::min(array[44], array[68]); + array[68] = std::max(array[44], array[68]); + array[44] = tmp; + tmp = std::min(array[45], array[69]); + array[69] = std::max(array[45], array[69]); + array[45] = tmp; + tmp = std::min(array[46], array[70]); + array[70] = std::max(array[46], array[70]); + array[46] = tmp; + tmp = std::min(array[47], array[71]); + array[71] = std::max(array[47], array[71]); + array[47] = tmp; + tmp = std::min(array[56], array[80]); + array[80] = std::max(array[56], array[80]); + array[56] = tmp; + tmp = std::min(array[8], array[16]); + array[16] = std::max(array[8], array[16]); + array[8] = tmp; + tmp = std::min(array[9], array[17]); + array[17] = std::max(array[9], array[17]); + array[9] = tmp; + tmp = std::min(array[10], array[18]); + array[18] = std::max(array[10], array[18]); + array[10] = tmp; + tmp = std::min(array[11], array[19]); + array[19] = std::max(array[11], array[19]); + array[11] = tmp; + tmp = std::min(array[12], array[20]); + array[20] = std::max(array[12], array[20]); + array[12] = tmp; + tmp = std::min(array[13], array[21]); + array[21] = std::max(array[13], array[21]); + array[13] = tmp; + tmp = std::min(array[14], array[22]); + array[22] = std::max(array[14], array[22]); + array[14] = tmp; + tmp = std::min(array[15], array[23]); + array[23] = std::max(array[15], array[23]); + array[15] = tmp; + tmp = std::min(array[24], array[32]); + array[32] = std::max(array[24], array[32]); + array[24] = tmp; + tmp = std::min(array[25], array[33]); + array[33] = std::max(array[25], array[33]); + array[25] = tmp; + tmp = std::min(array[26], array[34]); + array[34] = std::max(array[26], array[34]); + array[26] = tmp; + tmp = std::min(array[27], array[35]); + array[35] = std::max(array[27], array[35]); + array[27] = tmp; + tmp = std::min(array[28], array[36]); + array[36] = std::max(array[28], array[36]); + array[28] = tmp; + tmp = std::min(array[29], array[37]); + array[37] = std::max(array[29], array[37]); + array[29] = tmp; + tmp = std::min(array[30], array[38]); + array[38] = std::max(array[30], array[38]); + array[30] = tmp; + tmp = std::min(array[31], array[39]); + array[39] = std::max(array[31], array[39]); + array[31] = tmp; + tmp = std::min(array[40], array[48]); + array[48] = std::max(array[40], array[48]); + array[40] = tmp; + tmp = std::min(array[41], array[49]); + array[49] = std::max(array[41], array[49]); + array[41] = tmp; + tmp = std::min(array[42], array[50]); + array[50] = std::max(array[42], array[50]); + array[42] = tmp; + tmp = std::min(array[43], array[51]); + array[51] = std::max(array[43], array[51]); + array[43] = tmp; + tmp = std::min(array[44], array[52]); + array[52] = std::max(array[44], array[52]); + array[44] = tmp; + tmp = std::min(array[45], array[53]); + array[53] = std::max(array[45], array[53]); + array[45] = tmp; + tmp = std::min(array[46], array[54]); + array[54] = std::max(array[46], array[54]); + array[46] = tmp; + tmp = std::min(array[47], array[55]); + array[55] = std::max(array[47], array[55]); + array[47] = tmp; + tmp = std::min(array[56], array[64]); + array[64] = std::max(array[56], array[64]); + array[56] = tmp; + tmp = std::min(array[57], array[65]); + array[65] = std::max(array[57], array[65]); + array[57] = tmp; + tmp = std::min(array[58], array[66]); + array[66] = std::max(array[58], array[66]); + array[58] = tmp; + tmp = std::min(array[59], array[67]); + array[67] = std::max(array[59], array[67]); + array[59] = tmp; + tmp = std::min(array[60], array[68]); + array[68] = std::max(array[60], array[68]); + array[60] = tmp; + tmp = std::min(array[61], array[69]); + array[69] = std::max(array[61], array[69]); + array[61] = tmp; + tmp = std::min(array[62], array[70]); + array[70] = std::max(array[62], array[70]); + array[62] = tmp; + tmp = std::min(array[63], array[71]); + array[71] = std::max(array[63], array[71]); + array[63] = tmp; + tmp = std::min(array[72], array[80]); + array[80] = std::max(array[72], array[80]); + array[72] = tmp; + tmp = std::min(array[0], array[4]); + array[4] = std::max(array[0], array[4]); + array[0] = tmp; + tmp = std::min(array[1], array[5]); + array[5] = std::max(array[1], array[5]); + array[1] = tmp; + tmp = std::min(array[2], array[6]); + array[6] = std::max(array[2], array[6]); + array[2] = tmp; + tmp = std::min(array[3], array[7]); + array[7] = std::max(array[3], array[7]); + array[3] = tmp; + tmp = std::min(array[8], array[12]); + array[12] = std::max(array[8], array[12]); + array[8] = tmp; + tmp = std::min(array[9], array[13]); + array[13] = std::max(array[9], array[13]); + array[9] = tmp; + tmp = std::min(array[10], array[14]); + array[14] = std::max(array[10], array[14]); + array[10] = tmp; + tmp = std::min(array[11], array[15]); + array[15] = std::max(array[11], array[15]); + array[11] = tmp; + tmp = std::min(array[16], array[20]); + array[20] = std::max(array[16], array[20]); + array[16] = tmp; + tmp = std::min(array[17], array[21]); + array[21] = std::max(array[17], array[21]); + array[17] = tmp; + tmp = std::min(array[18], array[22]); + array[22] = std::max(array[18], array[22]); + array[18] = tmp; + tmp = std::min(array[19], array[23]); + array[23] = std::max(array[19], array[23]); + array[19] = tmp; + tmp = std::min(array[24], array[28]); + array[28] = std::max(array[24], array[28]); + array[24] = tmp; + tmp = std::min(array[25], array[29]); + array[29] = std::max(array[25], array[29]); + array[25] = tmp; + tmp = std::min(array[26], array[30]); + array[30] = std::max(array[26], array[30]); + array[26] = tmp; + tmp = std::min(array[27], array[31]); + array[31] = std::max(array[27], array[31]); + array[27] = tmp; + tmp = std::min(array[32], array[36]); + array[36] = std::max(array[32], array[36]); + array[32] = tmp; + tmp = std::min(array[33], array[37]); + array[37] = std::max(array[33], array[37]); + array[33] = tmp; + tmp = std::min(array[34], array[38]); + array[38] = std::max(array[34], array[38]); + array[34] = tmp; + tmp = std::min(array[35], array[39]); + array[39] = std::max(array[35], array[39]); + array[35] = tmp; + tmp = std::min(array[40], array[44]); + array[44] = std::max(array[40], array[44]); + array[40] = tmp; + tmp = std::min(array[41], array[45]); + array[45] = std::max(array[41], array[45]); + array[41] = tmp; + tmp = std::min(array[42], array[46]); + array[46] = std::max(array[42], array[46]); + array[42] = tmp; + tmp = std::min(array[43], array[47]); + array[47] = std::max(array[43], array[47]); + array[43] = tmp; + tmp = std::min(array[48], array[52]); + array[52] = std::max(array[48], array[52]); + array[48] = tmp; + tmp = std::min(array[49], array[53]); + array[53] = std::max(array[49], array[53]); + array[49] = tmp; + tmp = std::min(array[50], array[54]); + array[54] = std::max(array[50], array[54]); + array[50] = tmp; + tmp = std::min(array[51], array[55]); + array[55] = std::max(array[51], array[55]); + array[51] = tmp; + tmp = std::min(array[56], array[60]); + array[60] = std::max(array[56], array[60]); + array[56] = tmp; + tmp = std::min(array[57], array[61]); + array[61] = std::max(array[57], array[61]); + array[57] = tmp; + tmp = std::min(array[58], array[62]); + array[62] = std::max(array[58], array[62]); + array[58] = tmp; + tmp = std::min(array[59], array[63]); + array[63] = std::max(array[59], array[63]); + array[59] = tmp; + tmp = std::min(array[64], array[68]); + array[68] = std::max(array[64], array[68]); + array[64] = tmp; + tmp = std::min(array[65], array[69]); + array[69] = std::max(array[65], array[69]); + array[65] = tmp; + tmp = std::min(array[66], array[70]); + array[70] = std::max(array[66], array[70]); + array[66] = tmp; + tmp = std::min(array[67], array[71]); + array[71] = std::max(array[67], array[71]); + array[67] = tmp; + tmp = std::min(array[72], array[76]); + array[76] = std::max(array[72], array[76]); + array[72] = tmp; + tmp = std::min(array[73], array[77]); + array[77] = std::max(array[73], array[77]); + array[73] = tmp; + tmp = std::min(array[74], array[78]); + array[78] = std::max(array[74], array[78]); + array[74] = tmp; + tmp = std::min(array[75], array[79]); + array[79] = std::max(array[75], array[79]); + array[75] = tmp; + tmp = std::min(array[4], array[64]); + array[64] = std::max(array[4], array[64]); + array[4] = tmp; + tmp = std::min(array[5], array[65]); + array[65] = std::max(array[5], array[65]); + array[5] = tmp; + tmp = std::min(array[6], array[66]); + array[66] = std::max(array[6], array[66]); + array[6] = tmp; + tmp = std::min(array[7], array[67]); + array[67] = std::max(array[7], array[67]); + array[7] = tmp; + tmp = std::min(array[12], array[72]); + array[72] = std::max(array[12], array[72]); + array[12] = tmp; + tmp = std::min(array[13], array[73]); + array[73] = std::max(array[13], array[73]); + array[13] = tmp; + tmp = std::min(array[14], array[74]); + array[74] = std::max(array[14], array[74]); + array[14] = tmp; + tmp = std::min(array[15], array[75]); + array[75] = std::max(array[15], array[75]); + array[15] = tmp; + tmp = std::min(array[20], array[80]); + array[80] = std::max(array[20], array[80]); + array[20] = tmp; + tmp = std::min(array[4], array[32]); + array[32] = std::max(array[4], array[32]); + array[4] = tmp; + tmp = std::min(array[5], array[33]); + array[33] = std::max(array[5], array[33]); + array[5] = tmp; + tmp = std::min(array[6], array[34]); + array[34] = std::max(array[6], array[34]); + array[6] = tmp; + tmp = std::min(array[7], array[35]); + array[35] = std::max(array[7], array[35]); + array[7] = tmp; + tmp = std::min(array[12], array[40]); + array[40] = std::max(array[12], array[40]); + array[12] = tmp; + tmp = std::min(array[13], array[41]); + array[41] = std::max(array[13], array[41]); + array[13] = tmp; + tmp = std::min(array[14], array[42]); + array[42] = std::max(array[14], array[42]); + array[14] = tmp; + tmp = std::min(array[15], array[43]); + array[43] = std::max(array[15], array[43]); + array[15] = tmp; + tmp = std::min(array[20], array[48]); + array[48] = std::max(array[20], array[48]); + array[20] = tmp; + tmp = std::min(array[21], array[49]); + array[49] = std::max(array[21], array[49]); + array[21] = tmp; + tmp = std::min(array[22], array[50]); + array[50] = std::max(array[22], array[50]); + array[22] = tmp; + tmp = std::min(array[23], array[51]); + array[51] = std::max(array[23], array[51]); + array[23] = tmp; + tmp = std::min(array[28], array[56]); + array[56] = std::max(array[28], array[56]); + array[28] = tmp; + tmp = std::min(array[29], array[57]); + array[57] = std::max(array[29], array[57]); + array[29] = tmp; + tmp = std::min(array[30], array[58]); + array[58] = std::max(array[30], array[58]); + array[30] = tmp; + tmp = std::min(array[31], array[59]); + array[59] = std::max(array[31], array[59]); + array[31] = tmp; + tmp = std::min(array[36], array[64]); + array[64] = std::max(array[36], array[64]); + array[36] = tmp; + tmp = std::min(array[37], array[65]); + array[65] = std::max(array[37], array[65]); + array[37] = tmp; + tmp = std::min(array[38], array[66]); + array[66] = std::max(array[38], array[66]); + array[38] = tmp; + tmp = std::min(array[39], array[67]); + array[67] = std::max(array[39], array[67]); + array[39] = tmp; + tmp = std::min(array[44], array[72]); + array[72] = std::max(array[44], array[72]); + array[44] = tmp; + tmp = std::min(array[45], array[73]); + array[73] = std::max(array[45], array[73]); + array[45] = tmp; + tmp = std::min(array[46], array[74]); + array[74] = std::max(array[46], array[74]); + array[46] = tmp; + tmp = std::min(array[47], array[75]); + array[75] = std::max(array[47], array[75]); + array[47] = tmp; + tmp = std::min(array[52], array[80]); + array[80] = std::max(array[52], array[80]); + array[52] = tmp; + tmp = std::min(array[4], array[16]); + array[16] = std::max(array[4], array[16]); + array[4] = tmp; + tmp = std::min(array[5], array[17]); + array[17] = std::max(array[5], array[17]); + array[5] = tmp; + tmp = std::min(array[6], array[18]); + array[18] = std::max(array[6], array[18]); + array[6] = tmp; + tmp = std::min(array[7], array[19]); + array[19] = std::max(array[7], array[19]); + array[7] = tmp; + tmp = std::min(array[12], array[24]); + array[24] = std::max(array[12], array[24]); + array[12] = tmp; + tmp = std::min(array[13], array[25]); + array[25] = std::max(array[13], array[25]); + array[13] = tmp; + tmp = std::min(array[14], array[26]); + array[26] = std::max(array[14], array[26]); + array[14] = tmp; + tmp = std::min(array[15], array[27]); + array[27] = std::max(array[15], array[27]); + array[15] = tmp; + tmp = std::min(array[20], array[32]); + array[32] = std::max(array[20], array[32]); + array[20] = tmp; + tmp = std::min(array[21], array[33]); + array[33] = std::max(array[21], array[33]); + array[21] = tmp; + tmp = std::min(array[22], array[34]); + array[34] = std::max(array[22], array[34]); + array[22] = tmp; + tmp = std::min(array[23], array[35]); + array[35] = std::max(array[23], array[35]); + array[23] = tmp; + tmp = std::min(array[28], array[40]); + array[40] = std::max(array[28], array[40]); + array[28] = tmp; + tmp = std::min(array[29], array[41]); + array[41] = std::max(array[29], array[41]); + array[29] = tmp; + tmp = std::min(array[30], array[42]); + array[42] = std::max(array[30], array[42]); + array[30] = tmp; + tmp = std::min(array[31], array[43]); + array[43] = std::max(array[31], array[43]); + array[31] = tmp; + tmp = std::min(array[36], array[48]); + array[48] = std::max(array[36], array[48]); + array[36] = tmp; + tmp = std::min(array[37], array[49]); + array[49] = std::max(array[37], array[49]); + array[37] = tmp; + tmp = std::min(array[38], array[50]); + array[50] = std::max(array[38], array[50]); + array[38] = tmp; + tmp = std::min(array[39], array[51]); + array[51] = std::max(array[39], array[51]); + array[39] = tmp; + tmp = std::min(array[44], array[56]); + array[56] = std::max(array[44], array[56]); + array[44] = tmp; + tmp = std::min(array[45], array[57]); + array[57] = std::max(array[45], array[57]); + array[45] = tmp; + tmp = std::min(array[46], array[58]); + array[58] = std::max(array[46], array[58]); + array[46] = tmp; + tmp = std::min(array[47], array[59]); + array[59] = std::max(array[47], array[59]); + array[47] = tmp; + tmp = std::min(array[52], array[64]); + array[64] = std::max(array[52], array[64]); + array[52] = tmp; + tmp = std::min(array[53], array[65]); + array[65] = std::max(array[53], array[65]); + array[53] = tmp; + tmp = std::min(array[54], array[66]); + array[66] = std::max(array[54], array[66]); + array[54] = tmp; + tmp = std::min(array[55], array[67]); + array[67] = std::max(array[55], array[67]); + array[55] = tmp; + tmp = std::min(array[60], array[72]); + array[72] = std::max(array[60], array[72]); + array[60] = tmp; + tmp = std::min(array[61], array[73]); + array[73] = std::max(array[61], array[73]); + array[61] = tmp; + tmp = std::min(array[62], array[74]); + array[74] = std::max(array[62], array[74]); + array[62] = tmp; + tmp = std::min(array[63], array[75]); + array[75] = std::max(array[63], array[75]); + array[63] = tmp; + tmp = std::min(array[68], array[80]); + array[80] = std::max(array[68], array[80]); + array[68] = tmp; + tmp = std::min(array[4], array[8]); + array[8] = std::max(array[4], array[8]); + array[4] = tmp; + tmp = std::min(array[5], array[9]); + array[9] = std::max(array[5], array[9]); + array[5] = tmp; + tmp = std::min(array[6], array[10]); + array[10] = std::max(array[6], array[10]); + array[6] = tmp; + tmp = std::min(array[7], array[11]); + array[11] = std::max(array[7], array[11]); + array[7] = tmp; + tmp = std::min(array[12], array[16]); + array[16] = std::max(array[12], array[16]); + array[12] = tmp; + tmp = std::min(array[13], array[17]); + array[17] = std::max(array[13], array[17]); + array[13] = tmp; + tmp = std::min(array[14], array[18]); + array[18] = std::max(array[14], array[18]); + array[14] = tmp; + tmp = std::min(array[15], array[19]); + array[19] = std::max(array[15], array[19]); + array[15] = tmp; + tmp = std::min(array[20], array[24]); + array[24] = std::max(array[20], array[24]); + array[20] = tmp; + tmp = std::min(array[21], array[25]); + array[25] = std::max(array[21], array[25]); + array[21] = tmp; + tmp = std::min(array[22], array[26]); + array[26] = std::max(array[22], array[26]); + array[22] = tmp; + tmp = std::min(array[23], array[27]); + array[27] = std::max(array[23], array[27]); + array[23] = tmp; + tmp = std::min(array[28], array[32]); + array[32] = std::max(array[28], array[32]); + array[28] = tmp; + tmp = std::min(array[29], array[33]); + array[33] = std::max(array[29], array[33]); + array[29] = tmp; + tmp = std::min(array[30], array[34]); + array[34] = std::max(array[30], array[34]); + array[30] = tmp; + tmp = std::min(array[31], array[35]); + array[35] = std::max(array[31], array[35]); + array[31] = tmp; + tmp = std::min(array[36], array[40]); + array[40] = std::max(array[36], array[40]); + array[36] = tmp; + tmp = std::min(array[37], array[41]); + array[41] = std::max(array[37], array[41]); + array[37] = tmp; + tmp = std::min(array[38], array[42]); + array[42] = std::max(array[38], array[42]); + array[38] = tmp; + tmp = std::min(array[39], array[43]); + array[43] = std::max(array[39], array[43]); + array[39] = tmp; + tmp = std::min(array[44], array[48]); + array[48] = std::max(array[44], array[48]); + array[44] = tmp; + tmp = std::min(array[45], array[49]); + array[49] = std::max(array[45], array[49]); + array[45] = tmp; + tmp = std::min(array[46], array[50]); + array[50] = std::max(array[46], array[50]); + array[46] = tmp; + tmp = std::min(array[47], array[51]); + array[51] = std::max(array[47], array[51]); + array[47] = tmp; + tmp = std::min(array[52], array[56]); + array[56] = std::max(array[52], array[56]); + array[52] = tmp; + tmp = std::min(array[53], array[57]); + array[57] = std::max(array[53], array[57]); + array[53] = tmp; + tmp = std::min(array[54], array[58]); + array[58] = std::max(array[54], array[58]); + array[54] = tmp; + tmp = std::min(array[55], array[59]); + array[59] = std::max(array[55], array[59]); + array[55] = tmp; + tmp = std::min(array[60], array[64]); + array[64] = std::max(array[60], array[64]); + array[60] = tmp; + tmp = std::min(array[61], array[65]); + array[65] = std::max(array[61], array[65]); + array[61] = tmp; + tmp = std::min(array[62], array[66]); + array[66] = std::max(array[62], array[66]); + array[62] = tmp; + tmp = std::min(array[63], array[67]); + array[67] = std::max(array[63], array[67]); + array[63] = tmp; + tmp = std::min(array[68], array[72]); + array[72] = std::max(array[68], array[72]); + array[68] = tmp; + tmp = std::min(array[69], array[73]); + array[73] = std::max(array[69], array[73]); + array[69] = tmp; + tmp = std::min(array[70], array[74]); + array[74] = std::max(array[70], array[74]); + array[70] = tmp; + tmp = std::min(array[71], array[75]); + array[75] = std::max(array[71], array[75]); + array[71] = tmp; + tmp = std::min(array[76], array[80]); + array[80] = std::max(array[76], array[80]); + array[76] = tmp; + tmp = std::min(array[0], array[2]); + array[2] = std::max(array[0], array[2]); + array[0] = tmp; + tmp = std::min(array[1], array[3]); + array[3] = std::max(array[1], array[3]); + array[1] = tmp; + tmp = std::min(array[4], array[6]); + array[6] = std::max(array[4], array[6]); + array[4] = tmp; + tmp = std::min(array[5], array[7]); + array[7] = std::max(array[5], array[7]); + array[5] = tmp; + tmp = std::min(array[8], array[10]); + array[10] = std::max(array[8], array[10]); + array[8] = tmp; + tmp = std::min(array[9], array[11]); + array[11] = std::max(array[9], array[11]); + array[9] = tmp; + tmp = std::min(array[12], array[14]); + array[14] = std::max(array[12], array[14]); + array[12] = tmp; + tmp = std::min(array[13], array[15]); + array[15] = std::max(array[13], array[15]); + array[13] = tmp; + tmp = std::min(array[16], array[18]); + array[18] = std::max(array[16], array[18]); + array[16] = tmp; + tmp = std::min(array[17], array[19]); + array[19] = std::max(array[17], array[19]); + array[17] = tmp; + tmp = std::min(array[20], array[22]); + array[22] = std::max(array[20], array[22]); + array[20] = tmp; + tmp = std::min(array[21], array[23]); + array[23] = std::max(array[21], array[23]); + array[21] = tmp; + tmp = std::min(array[24], array[26]); + array[26] = std::max(array[24], array[26]); + array[24] = tmp; + tmp = std::min(array[25], array[27]); + array[27] = std::max(array[25], array[27]); + array[25] = tmp; + tmp = std::min(array[28], array[30]); + array[30] = std::max(array[28], array[30]); + array[28] = tmp; + tmp = std::min(array[29], array[31]); + array[31] = std::max(array[29], array[31]); + array[29] = tmp; + tmp = std::min(array[32], array[34]); + array[34] = std::max(array[32], array[34]); + array[32] = tmp; + tmp = std::min(array[33], array[35]); + array[35] = std::max(array[33], array[35]); + array[33] = tmp; + tmp = std::min(array[36], array[38]); + array[38] = std::max(array[36], array[38]); + array[36] = tmp; + tmp = std::min(array[37], array[39]); + array[39] = std::max(array[37], array[39]); + array[37] = tmp; + tmp = std::min(array[40], array[42]); + array[42] = std::max(array[40], array[42]); + array[40] = tmp; + tmp = std::min(array[41], array[43]); + array[43] = std::max(array[41], array[43]); + array[41] = tmp; + tmp = std::min(array[44], array[46]); + array[46] = std::max(array[44], array[46]); + array[44] = tmp; + tmp = std::min(array[45], array[47]); + array[47] = std::max(array[45], array[47]); + array[45] = tmp; + tmp = std::min(array[48], array[50]); + array[50] = std::max(array[48], array[50]); + array[48] = tmp; + tmp = std::min(array[49], array[51]); + array[51] = std::max(array[49], array[51]); + array[49] = tmp; + tmp = std::min(array[52], array[54]); + array[54] = std::max(array[52], array[54]); + array[52] = tmp; + tmp = std::min(array[53], array[55]); + array[55] = std::max(array[53], array[55]); + array[53] = tmp; + tmp = std::min(array[56], array[58]); + array[58] = std::max(array[56], array[58]); + array[56] = tmp; + tmp = std::min(array[57], array[59]); + array[59] = std::max(array[57], array[59]); + array[57] = tmp; + tmp = std::min(array[60], array[62]); + array[62] = std::max(array[60], array[62]); + array[60] = tmp; + tmp = std::min(array[61], array[63]); + array[63] = std::max(array[61], array[63]); + array[61] = tmp; + tmp = std::min(array[64], array[66]); + array[66] = std::max(array[64], array[66]); + array[64] = tmp; + tmp = std::min(array[65], array[67]); + array[67] = std::max(array[65], array[67]); + array[65] = tmp; + tmp = std::min(array[68], array[70]); + array[70] = std::max(array[68], array[70]); + array[68] = tmp; + tmp = std::min(array[69], array[71]); + array[71] = std::max(array[69], array[71]); + array[69] = tmp; + tmp = std::min(array[72], array[74]); + array[74] = std::max(array[72], array[74]); + array[72] = tmp; + tmp = std::min(array[73], array[75]); + array[75] = std::max(array[73], array[75]); + array[73] = tmp; + tmp = std::min(array[76], array[78]); + array[78] = std::max(array[76], array[78]); + array[76] = tmp; + tmp = std::min(array[77], array[79]); + array[79] = std::max(array[77], array[79]); + array[77] = tmp; + tmp = std::min(array[2], array[64]); + array[64] = std::max(array[2], array[64]); + array[2] = tmp; + tmp = std::min(array[3], array[65]); + array[65] = std::max(array[3], array[65]); + array[3] = tmp; + tmp = std::min(array[6], array[68]); + array[68] = std::max(array[6], array[68]); + array[6] = tmp; + tmp = std::min(array[7], array[69]); + array[69] = std::max(array[7], array[69]); + array[7] = tmp; + tmp = std::min(array[10], array[72]); + array[72] = std::max(array[10], array[72]); + array[10] = tmp; + tmp = std::min(array[11], array[73]); + array[73] = std::max(array[11], array[73]); + array[11] = tmp; + tmp = std::min(array[14], array[76]); + array[76] = std::max(array[14], array[76]); + array[14] = tmp; + tmp = std::min(array[15], array[77]); + array[77] = std::max(array[15], array[77]); + array[15] = tmp; + tmp = std::min(array[18], array[80]); + array[80] = std::max(array[18], array[80]); + array[18] = tmp; + tmp = std::min(array[2], array[32]); + array[32] = std::max(array[2], array[32]); + array[2] = tmp; + tmp = std::min(array[3], array[33]); + array[33] = std::max(array[3], array[33]); + array[3] = tmp; + tmp = std::min(array[6], array[36]); + array[36] = std::max(array[6], array[36]); + array[6] = tmp; + tmp = std::min(array[7], array[37]); + array[37] = std::max(array[7], array[37]); + array[7] = tmp; + tmp = std::min(array[10], array[40]); + array[40] = std::max(array[10], array[40]); + array[10] = tmp; + tmp = std::min(array[11], array[41]); + array[41] = std::max(array[11], array[41]); + array[11] = tmp; + tmp = std::min(array[14], array[44]); + array[44] = std::max(array[14], array[44]); + array[14] = tmp; + tmp = std::min(array[15], array[45]); + array[45] = std::max(array[15], array[45]); + array[15] = tmp; + tmp = std::min(array[18], array[48]); + array[48] = std::max(array[18], array[48]); + array[18] = tmp; + tmp = std::min(array[19], array[49]); + array[49] = std::max(array[19], array[49]); + array[19] = tmp; + tmp = std::min(array[22], array[52]); + array[52] = std::max(array[22], array[52]); + array[22] = tmp; + tmp = std::min(array[23], array[53]); + array[53] = std::max(array[23], array[53]); + array[23] = tmp; + tmp = std::min(array[26], array[56]); + array[56] = std::max(array[26], array[56]); + array[26] = tmp; + tmp = std::min(array[27], array[57]); + array[57] = std::max(array[27], array[57]); + array[27] = tmp; + tmp = std::min(array[30], array[60]); + array[60] = std::max(array[30], array[60]); + array[30] = tmp; + tmp = std::min(array[31], array[61]); + array[61] = std::max(array[31], array[61]); + array[31] = tmp; + tmp = std::min(array[34], array[64]); + array[64] = std::max(array[34], array[64]); + array[34] = tmp; + tmp = std::min(array[35], array[65]); + array[65] = std::max(array[35], array[65]); + array[35] = tmp; + tmp = std::min(array[38], array[68]); + array[68] = std::max(array[38], array[68]); + array[38] = tmp; + tmp = std::min(array[39], array[69]); + array[69] = std::max(array[39], array[69]); + array[39] = tmp; + tmp = std::min(array[42], array[72]); + array[72] = std::max(array[42], array[72]); + array[42] = tmp; + tmp = std::min(array[43], array[73]); + array[73] = std::max(array[43], array[73]); + array[43] = tmp; + tmp = std::min(array[46], array[76]); + array[76] = std::max(array[46], array[76]); + array[46] = tmp; + tmp = std::min(array[47], array[77]); + array[77] = std::max(array[47], array[77]); + array[47] = tmp; + tmp = std::min(array[50], array[80]); + array[80] = std::max(array[50], array[80]); + array[50] = tmp; + tmp = std::min(array[2], array[16]); + array[16] = std::max(array[2], array[16]); + array[2] = tmp; + tmp = std::min(array[3], array[17]); + array[17] = std::max(array[3], array[17]); + array[3] = tmp; + tmp = std::min(array[6], array[20]); + array[20] = std::max(array[6], array[20]); + array[6] = tmp; + tmp = std::min(array[7], array[21]); + array[21] = std::max(array[7], array[21]); + array[7] = tmp; + tmp = std::min(array[10], array[24]); + array[24] = std::max(array[10], array[24]); + array[10] = tmp; + tmp = std::min(array[11], array[25]); + array[25] = std::max(array[11], array[25]); + array[11] = tmp; + tmp = std::min(array[14], array[28]); + array[28] = std::max(array[14], array[28]); + array[14] = tmp; + tmp = std::min(array[15], array[29]); + array[29] = std::max(array[15], array[29]); + array[15] = tmp; + tmp = std::min(array[18], array[32]); + array[32] = std::max(array[18], array[32]); + array[18] = tmp; + tmp = std::min(array[19], array[33]); + array[33] = std::max(array[19], array[33]); + array[19] = tmp; + tmp = std::min(array[22], array[36]); + array[36] = std::max(array[22], array[36]); + array[22] = tmp; + tmp = std::min(array[23], array[37]); + array[37] = std::max(array[23], array[37]); + array[23] = tmp; + tmp = std::min(array[26], array[40]); + array[40] = std::max(array[26], array[40]); + array[26] = tmp; + tmp = std::min(array[27], array[41]); + array[41] = std::max(array[27], array[41]); + array[27] = tmp; + tmp = std::min(array[30], array[44]); + array[44] = std::max(array[30], array[44]); + array[30] = tmp; + tmp = std::min(array[31], array[45]); + array[45] = std::max(array[31], array[45]); + array[31] = tmp; + tmp = std::min(array[34], array[48]); + array[48] = std::max(array[34], array[48]); + array[34] = tmp; + tmp = std::min(array[35], array[49]); + array[49] = std::max(array[35], array[49]); + array[35] = tmp; + tmp = std::min(array[38], array[52]); + array[52] = std::max(array[38], array[52]); + array[38] = tmp; + tmp = std::min(array[39], array[53]); + array[53] = std::max(array[39], array[53]); + array[39] = tmp; + tmp = std::min(array[42], array[56]); + array[56] = std::max(array[42], array[56]); + array[42] = tmp; + tmp = std::min(array[43], array[57]); + array[57] = std::max(array[43], array[57]); + array[43] = tmp; + tmp = std::min(array[46], array[60]); + array[60] = std::max(array[46], array[60]); + array[46] = tmp; + tmp = std::min(array[47], array[61]); + array[61] = std::max(array[47], array[61]); + array[47] = tmp; + tmp = std::min(array[50], array[64]); + array[64] = std::max(array[50], array[64]); + array[50] = tmp; + tmp = std::min(array[51], array[65]); + array[65] = std::max(array[51], array[65]); + array[51] = tmp; + tmp = std::min(array[54], array[68]); + array[68] = std::max(array[54], array[68]); + array[54] = tmp; + tmp = std::min(array[55], array[69]); + array[69] = std::max(array[55], array[69]); + array[55] = tmp; + tmp = std::min(array[58], array[72]); + array[72] = std::max(array[58], array[72]); + array[58] = tmp; + tmp = std::min(array[59], array[73]); + array[73] = std::max(array[59], array[73]); + array[59] = tmp; + tmp = std::min(array[62], array[76]); + array[76] = std::max(array[62], array[76]); + array[62] = tmp; + tmp = std::min(array[63], array[77]); + array[77] = std::max(array[63], array[77]); + array[63] = tmp; + tmp = std::min(array[66], array[80]); + array[80] = std::max(array[66], array[80]); + array[66] = tmp; + tmp = std::min(array[2], array[8]); + array[8] = std::max(array[2], array[8]); + array[2] = tmp; + tmp = std::min(array[3], array[9]); + array[9] = std::max(array[3], array[9]); + array[3] = tmp; + tmp = std::min(array[6], array[12]); + array[12] = std::max(array[6], array[12]); + array[6] = tmp; + tmp = std::min(array[7], array[13]); + array[13] = std::max(array[7], array[13]); + array[7] = tmp; + tmp = std::min(array[10], array[16]); + array[16] = std::max(array[10], array[16]); + array[10] = tmp; + tmp = std::min(array[11], array[17]); + array[17] = std::max(array[11], array[17]); + array[11] = tmp; + tmp = std::min(array[14], array[20]); + array[20] = std::max(array[14], array[20]); + array[14] = tmp; + tmp = std::min(array[15], array[21]); + array[21] = std::max(array[15], array[21]); + array[15] = tmp; + tmp = std::min(array[18], array[24]); + array[24] = std::max(array[18], array[24]); + array[18] = tmp; + tmp = std::min(array[19], array[25]); + array[25] = std::max(array[19], array[25]); + array[19] = tmp; + tmp = std::min(array[22], array[28]); + array[28] = std::max(array[22], array[28]); + array[22] = tmp; + tmp = std::min(array[23], array[29]); + array[29] = std::max(array[23], array[29]); + array[23] = tmp; + tmp = std::min(array[26], array[32]); + array[32] = std::max(array[26], array[32]); + array[26] = tmp; + tmp = std::min(array[27], array[33]); + array[33] = std::max(array[27], array[33]); + array[27] = tmp; + tmp = std::min(array[30], array[36]); + array[36] = std::max(array[30], array[36]); + array[30] = tmp; + tmp = std::min(array[31], array[37]); + array[37] = std::max(array[31], array[37]); + array[31] = tmp; + tmp = std::min(array[34], array[40]); + array[40] = std::max(array[34], array[40]); + array[34] = tmp; + tmp = std::min(array[35], array[41]); + array[41] = std::max(array[35], array[41]); + array[35] = tmp; + tmp = std::min(array[38], array[44]); + array[44] = std::max(array[38], array[44]); + array[38] = tmp; + tmp = std::min(array[39], array[45]); + array[45] = std::max(array[39], array[45]); + array[39] = tmp; + tmp = std::min(array[42], array[48]); + array[48] = std::max(array[42], array[48]); + array[42] = tmp; + tmp = std::min(array[43], array[49]); + array[49] = std::max(array[43], array[49]); + array[43] = tmp; + tmp = std::min(array[46], array[52]); + array[52] = std::max(array[46], array[52]); + array[46] = tmp; + tmp = std::min(array[47], array[53]); + array[53] = std::max(array[47], array[53]); + array[47] = tmp; + tmp = std::min(array[50], array[56]); + array[56] = std::max(array[50], array[56]); + array[50] = tmp; + tmp = std::min(array[51], array[57]); + array[57] = std::max(array[51], array[57]); + array[51] = tmp; + tmp = std::min(array[54], array[60]); + array[60] = std::max(array[54], array[60]); + array[54] = tmp; + tmp = std::min(array[55], array[61]); + array[61] = std::max(array[55], array[61]); + array[55] = tmp; + tmp = std::min(array[58], array[64]); + array[64] = std::max(array[58], array[64]); + array[58] = tmp; + tmp = std::min(array[59], array[65]); + array[65] = std::max(array[59], array[65]); + array[59] = tmp; + tmp = std::min(array[62], array[68]); + array[68] = std::max(array[62], array[68]); + array[62] = tmp; + tmp = std::min(array[63], array[69]); + array[69] = std::max(array[63], array[69]); + array[63] = tmp; + tmp = std::min(array[66], array[72]); + array[72] = std::max(array[66], array[72]); + array[66] = tmp; + tmp = std::min(array[67], array[73]); + array[73] = std::max(array[67], array[73]); + array[67] = tmp; + tmp = std::min(array[70], array[76]); + array[76] = std::max(array[70], array[76]); + array[70] = tmp; + tmp = std::min(array[71], array[77]); + array[77] = std::max(array[71], array[77]); + array[71] = tmp; + tmp = std::min(array[74], array[80]); + array[80] = std::max(array[74], array[80]); + array[74] = tmp; + tmp = std::min(array[2], array[4]); + array[4] = std::max(array[2], array[4]); + array[2] = tmp; + tmp = std::min(array[3], array[5]); + array[5] = std::max(array[3], array[5]); + array[3] = tmp; + tmp = std::min(array[6], array[8]); + array[8] = std::max(array[6], array[8]); + array[6] = tmp; + tmp = std::min(array[7], array[9]); + array[9] = std::max(array[7], array[9]); + array[7] = tmp; + tmp = std::min(array[10], array[12]); + array[12] = std::max(array[10], array[12]); + array[10] = tmp; + tmp = std::min(array[11], array[13]); + array[13] = std::max(array[11], array[13]); + array[11] = tmp; + tmp = std::min(array[14], array[16]); + array[16] = std::max(array[14], array[16]); + array[14] = tmp; + tmp = std::min(array[15], array[17]); + array[17] = std::max(array[15], array[17]); + array[15] = tmp; + tmp = std::min(array[18], array[20]); + array[20] = std::max(array[18], array[20]); + array[18] = tmp; + tmp = std::min(array[19], array[21]); + array[21] = std::max(array[19], array[21]); + array[19] = tmp; + tmp = std::min(array[22], array[24]); + array[24] = std::max(array[22], array[24]); + array[22] = tmp; + tmp = std::min(array[23], array[25]); + array[25] = std::max(array[23], array[25]); + array[23] = tmp; + tmp = std::min(array[26], array[28]); + array[28] = std::max(array[26], array[28]); + array[26] = tmp; + tmp = std::min(array[27], array[29]); + array[29] = std::max(array[27], array[29]); + array[27] = tmp; + tmp = std::min(array[30], array[32]); + array[32] = std::max(array[30], array[32]); + array[30] = tmp; + tmp = std::min(array[31], array[33]); + array[33] = std::max(array[31], array[33]); + array[31] = tmp; + tmp = std::min(array[34], array[36]); + array[36] = std::max(array[34], array[36]); + array[34] = tmp; + tmp = std::min(array[35], array[37]); + array[37] = std::max(array[35], array[37]); + array[35] = tmp; + tmp = std::min(array[38], array[40]); + array[40] = std::max(array[38], array[40]); + array[38] = tmp; + tmp = std::min(array[39], array[41]); + array[41] = std::max(array[39], array[41]); + array[39] = tmp; + tmp = std::min(array[42], array[44]); + array[44] = std::max(array[42], array[44]); + array[42] = tmp; + tmp = std::min(array[43], array[45]); + array[45] = std::max(array[43], array[45]); + array[43] = tmp; + tmp = std::min(array[46], array[48]); + array[48] = std::max(array[46], array[48]); + array[46] = tmp; + tmp = std::min(array[47], array[49]); + array[49] = std::max(array[47], array[49]); + array[47] = tmp; + tmp = std::min(array[50], array[52]); + array[52] = std::max(array[50], array[52]); + array[50] = tmp; + tmp = std::min(array[51], array[53]); + array[53] = std::max(array[51], array[53]); + array[51] = tmp; + tmp = std::min(array[54], array[56]); + array[56] = std::max(array[54], array[56]); + array[54] = tmp; + tmp = std::min(array[55], array[57]); + array[57] = std::max(array[55], array[57]); + array[55] = tmp; + tmp = std::min(array[58], array[60]); + array[60] = std::max(array[58], array[60]); + array[58] = tmp; + tmp = std::min(array[59], array[61]); + array[61] = std::max(array[59], array[61]); + array[59] = tmp; + tmp = std::min(array[62], array[64]); + array[64] = std::max(array[62], array[64]); + array[62] = tmp; + tmp = std::min(array[63], array[65]); + array[65] = std::max(array[63], array[65]); + array[63] = tmp; + tmp = std::min(array[66], array[68]); + array[68] = std::max(array[66], array[68]); + array[66] = tmp; + tmp = std::min(array[67], array[69]); + array[69] = std::max(array[67], array[69]); + array[67] = tmp; + tmp = std::min(array[70], array[72]); + array[72] = std::max(array[70], array[72]); + array[70] = tmp; + tmp = std::min(array[71], array[73]); + array[73] = std::max(array[71], array[73]); + array[71] = tmp; + tmp = std::min(array[74], array[76]); + array[76] = std::max(array[74], array[76]); + array[74] = tmp; + tmp = std::min(array[75], array[77]); + array[77] = std::max(array[75], array[77]); + array[75] = tmp; + tmp = std::min(array[78], array[80]); + array[80] = std::max(array[78], array[80]); + array[78] = tmp; + array[1] = std::max(array[0], array[1]); + array[3] = std::max(array[2], array[3]); + array[5] = std::max(array[4], array[5]); + array[7] = std::max(array[6], array[7]); + array[9] = std::max(array[8], array[9]); + array[11] = std::max(array[10], array[11]); + array[13] = std::max(array[12], array[13]); + array[15] = std::max(array[14], array[15]); + array[17] = std::max(array[16], array[17]); + array[19] = std::max(array[18], array[19]); + array[21] = std::max(array[20], array[21]); + array[23] = std::max(array[22], array[23]); + array[25] = std::max(array[24], array[25]); + array[27] = std::max(array[26], array[27]); + array[29] = std::max(array[28], array[29]); + array[31] = std::max(array[30], array[31]); + array[33] = std::max(array[32], array[33]); + array[35] = std::max(array[34], array[35]); + array[37] = std::max(array[36], array[37]); + array[39] = std::max(array[38], array[39]); + array[40] = std::min(array[40], array[41]); + array[42] = std::min(array[42], array[43]); + array[44] = std::min(array[44], array[45]); + array[46] = std::min(array[46], array[47]); + array[48] = std::min(array[48], array[49]); + array[50] = std::min(array[50], array[51]); + array[52] = std::min(array[52], array[53]); + array[54] = std::min(array[54], array[55]); + array[56] = std::min(array[56], array[57]); + array[58] = std::min(array[58], array[59]); + array[60] = std::min(array[60], array[61]); + array[62] = std::min(array[62], array[63]); + array[64] = std::min(array[64], array[65]); + array[66] = std::min(array[66], array[67]); + array[68] = std::min(array[68], array[69]); + array[70] = std::min(array[70], array[71]); + array[72] = std::min(array[72], array[73]); + array[74] = std::min(array[74], array[75]); + array[76] = std::min(array[76], array[77]); + array[78] = std::min(array[78], array[79]); + array[64] = std::max(array[1], array[64]); + array[66] = std::max(array[3], array[66]); + array[68] = std::max(array[5], array[68]); + array[70] = std::max(array[7], array[70]); + array[9] = std::min(array[9], array[72]); + array[11] = std::min(array[11], array[74]); + array[13] = std::min(array[13], array[76]); + array[15] = std::min(array[15], array[78]); + array[17] = std::min(array[17], array[80]); + array[40] = std::max(array[9], array[40]); + array[42] = std::max(array[11], array[42]); + array[44] = std::max(array[13], array[44]); + array[46] = std::max(array[15], array[46]); + array[48] = std::max(array[17], array[48]); + array[50] = std::max(array[19], array[50]); + array[52] = std::max(array[21], array[52]); + array[54] = std::max(array[23], array[54]); + array[25] = std::min(array[25], array[56]); + array[27] = std::min(array[27], array[58]); + array[29] = std::min(array[29], array[60]); + array[31] = std::min(array[31], array[62]); + array[33] = std::min(array[33], array[64]); + array[35] = std::min(array[35], array[66]); + array[37] = std::min(array[37], array[68]); + array[39] = std::min(array[39], array[70]); + array[40] = std::max(array[25], array[40]); + array[42] = std::max(array[27], array[42]); + array[44] = std::max(array[29], array[44]); + array[46] = std::max(array[31], array[46]); + array[33] = std::min(array[33], array[48]); + array[35] = std::min(array[35], array[50]); + array[37] = std::min(array[37], array[52]); + array[39] = std::min(array[39], array[54]); + array[40] = std::max(array[33], array[40]); + array[42] = std::max(array[35], array[42]); + array[37] = std::min(array[37], array[44]); + array[39] = std::min(array[39], array[46]); + array[40] = std::max(array[37], array[40]); + array[39] = std::min(array[39], array[42]); + return std::max(array[39], array[40]); +} + +#ifdef __SSE2__ +template<> +inline vfloat median(std::array array) +{ + vfloat tmp = vminf(array[0], array[64]); + array[64] = vmaxf(array[0], array[64]); + array[0] = tmp; + tmp = vminf(array[1], array[65]); + array[65] = vmaxf(array[1], array[65]); + array[1] = tmp; + tmp = vminf(array[2], array[66]); + array[66] = vmaxf(array[2], array[66]); + array[2] = tmp; + tmp = vminf(array[3], array[67]); + array[67] = vmaxf(array[3], array[67]); + array[3] = tmp; + tmp = vminf(array[4], array[68]); + array[68] = vmaxf(array[4], array[68]); + array[4] = tmp; + tmp = vminf(array[5], array[69]); + array[69] = vmaxf(array[5], array[69]); + array[5] = tmp; + tmp = vminf(array[6], array[70]); + array[70] = vmaxf(array[6], array[70]); + array[6] = tmp; + tmp = vminf(array[7], array[71]); + array[71] = vmaxf(array[7], array[71]); + array[7] = tmp; + tmp = vminf(array[8], array[72]); + array[72] = vmaxf(array[8], array[72]); + array[8] = tmp; + tmp = vminf(array[9], array[73]); + array[73] = vmaxf(array[9], array[73]); + array[9] = tmp; + tmp = vminf(array[10], array[74]); + array[74] = vmaxf(array[10], array[74]); + array[10] = tmp; + tmp = vminf(array[11], array[75]); + array[75] = vmaxf(array[11], array[75]); + array[11] = tmp; + tmp = vminf(array[12], array[76]); + array[76] = vmaxf(array[12], array[76]); + array[12] = tmp; + tmp = vminf(array[13], array[77]); + array[77] = vmaxf(array[13], array[77]); + array[13] = tmp; + tmp = vminf(array[14], array[78]); + array[78] = vmaxf(array[14], array[78]); + array[14] = tmp; + tmp = vminf(array[15], array[79]); + array[79] = vmaxf(array[15], array[79]); + array[15] = tmp; + tmp = vminf(array[16], array[80]); + array[80] = vmaxf(array[16], array[80]); + array[16] = tmp; + tmp = vminf(array[0], array[32]); + array[32] = vmaxf(array[0], array[32]); + array[0] = tmp; + tmp = vminf(array[1], array[33]); + array[33] = vmaxf(array[1], array[33]); + array[1] = tmp; + tmp = vminf(array[2], array[34]); + array[34] = vmaxf(array[2], array[34]); + array[2] = tmp; + tmp = vminf(array[3], array[35]); + array[35] = vmaxf(array[3], array[35]); + array[3] = tmp; + tmp = vminf(array[4], array[36]); + array[36] = vmaxf(array[4], array[36]); + array[4] = tmp; + tmp = vminf(array[5], array[37]); + array[37] = vmaxf(array[5], array[37]); + array[5] = tmp; + tmp = vminf(array[6], array[38]); + array[38] = vmaxf(array[6], array[38]); + array[6] = tmp; + tmp = vminf(array[7], array[39]); + array[39] = vmaxf(array[7], array[39]); + array[7] = tmp; + tmp = vminf(array[8], array[40]); + array[40] = vmaxf(array[8], array[40]); + array[8] = tmp; + tmp = vminf(array[9], array[41]); + array[41] = vmaxf(array[9], array[41]); + array[9] = tmp; + tmp = vminf(array[10], array[42]); + array[42] = vmaxf(array[10], array[42]); + array[10] = tmp; + tmp = vminf(array[11], array[43]); + array[43] = vmaxf(array[11], array[43]); + array[11] = tmp; + tmp = vminf(array[12], array[44]); + array[44] = vmaxf(array[12], array[44]); + array[12] = tmp; + tmp = vminf(array[13], array[45]); + array[45] = vmaxf(array[13], array[45]); + array[13] = tmp; + tmp = vminf(array[14], array[46]); + array[46] = vmaxf(array[14], array[46]); + array[14] = tmp; + tmp = vminf(array[15], array[47]); + array[47] = vmaxf(array[15], array[47]); + array[15] = tmp; + tmp = vminf(array[16], array[48]); + array[48] = vmaxf(array[16], array[48]); + array[16] = tmp; + tmp = vminf(array[17], array[49]); + array[49] = vmaxf(array[17], array[49]); + array[17] = tmp; + tmp = vminf(array[18], array[50]); + array[50] = vmaxf(array[18], array[50]); + array[18] = tmp; + tmp = vminf(array[19], array[51]); + array[51] = vmaxf(array[19], array[51]); + array[19] = tmp; + tmp = vminf(array[20], array[52]); + array[52] = vmaxf(array[20], array[52]); + array[20] = tmp; + tmp = vminf(array[21], array[53]); + array[53] = vmaxf(array[21], array[53]); + array[21] = tmp; + tmp = vminf(array[22], array[54]); + array[54] = vmaxf(array[22], array[54]); + array[22] = tmp; + tmp = vminf(array[23], array[55]); + array[55] = vmaxf(array[23], array[55]); + array[23] = tmp; + tmp = vminf(array[24], array[56]); + array[56] = vmaxf(array[24], array[56]); + array[24] = tmp; + tmp = vminf(array[25], array[57]); + array[57] = vmaxf(array[25], array[57]); + array[25] = tmp; + tmp = vminf(array[26], array[58]); + array[58] = vmaxf(array[26], array[58]); + array[26] = tmp; + tmp = vminf(array[27], array[59]); + array[59] = vmaxf(array[27], array[59]); + array[27] = tmp; + tmp = vminf(array[28], array[60]); + array[60] = vmaxf(array[28], array[60]); + array[28] = tmp; + tmp = vminf(array[29], array[61]); + array[61] = vmaxf(array[29], array[61]); + array[29] = tmp; + tmp = vminf(array[30], array[62]); + array[62] = vmaxf(array[30], array[62]); + array[30] = tmp; + tmp = vminf(array[31], array[63]); + array[63] = vmaxf(array[31], array[63]); + array[31] = tmp; + tmp = vminf(array[32], array[64]); + array[64] = vmaxf(array[32], array[64]); + array[32] = tmp; + tmp = vminf(array[33], array[65]); + array[65] = vmaxf(array[33], array[65]); + array[33] = tmp; + tmp = vminf(array[34], array[66]); + array[66] = vmaxf(array[34], array[66]); + array[34] = tmp; + tmp = vminf(array[35], array[67]); + array[67] = vmaxf(array[35], array[67]); + array[35] = tmp; + tmp = vminf(array[36], array[68]); + array[68] = vmaxf(array[36], array[68]); + array[36] = tmp; + tmp = vminf(array[37], array[69]); + array[69] = vmaxf(array[37], array[69]); + array[37] = tmp; + tmp = vminf(array[38], array[70]); + array[70] = vmaxf(array[38], array[70]); + array[38] = tmp; + tmp = vminf(array[39], array[71]); + array[71] = vmaxf(array[39], array[71]); + array[39] = tmp; + tmp = vminf(array[40], array[72]); + array[72] = vmaxf(array[40], array[72]); + array[40] = tmp; + tmp = vminf(array[41], array[73]); + array[73] = vmaxf(array[41], array[73]); + array[41] = tmp; + tmp = vminf(array[42], array[74]); + array[74] = vmaxf(array[42], array[74]); + array[42] = tmp; + tmp = vminf(array[43], array[75]); + array[75] = vmaxf(array[43], array[75]); + array[43] = tmp; + tmp = vminf(array[44], array[76]); + array[76] = vmaxf(array[44], array[76]); + array[44] = tmp; + tmp = vminf(array[45], array[77]); + array[77] = vmaxf(array[45], array[77]); + array[45] = tmp; + tmp = vminf(array[46], array[78]); + array[78] = vmaxf(array[46], array[78]); + array[46] = tmp; + tmp = vminf(array[47], array[79]); + array[79] = vmaxf(array[47], array[79]); + array[47] = tmp; + tmp = vminf(array[48], array[80]); + array[80] = vmaxf(array[48], array[80]); + array[48] = tmp; + tmp = vminf(array[0], array[16]); + array[16] = vmaxf(array[0], array[16]); + array[0] = tmp; + tmp = vminf(array[1], array[17]); + array[17] = vmaxf(array[1], array[17]); + array[1] = tmp; + tmp = vminf(array[2], array[18]); + array[18] = vmaxf(array[2], array[18]); + array[2] = tmp; + tmp = vminf(array[3], array[19]); + array[19] = vmaxf(array[3], array[19]); + array[3] = tmp; + tmp = vminf(array[4], array[20]); + array[20] = vmaxf(array[4], array[20]); + array[4] = tmp; + tmp = vminf(array[5], array[21]); + array[21] = vmaxf(array[5], array[21]); + array[5] = tmp; + tmp = vminf(array[6], array[22]); + array[22] = vmaxf(array[6], array[22]); + array[6] = tmp; + tmp = vminf(array[7], array[23]); + array[23] = vmaxf(array[7], array[23]); + array[7] = tmp; + tmp = vminf(array[8], array[24]); + array[24] = vmaxf(array[8], array[24]); + array[8] = tmp; + tmp = vminf(array[9], array[25]); + array[25] = vmaxf(array[9], array[25]); + array[9] = tmp; + tmp = vminf(array[10], array[26]); + array[26] = vmaxf(array[10], array[26]); + array[10] = tmp; + tmp = vminf(array[11], array[27]); + array[27] = vmaxf(array[11], array[27]); + array[11] = tmp; + tmp = vminf(array[12], array[28]); + array[28] = vmaxf(array[12], array[28]); + array[12] = tmp; + tmp = vminf(array[13], array[29]); + array[29] = vmaxf(array[13], array[29]); + array[13] = tmp; + tmp = vminf(array[14], array[30]); + array[30] = vmaxf(array[14], array[30]); + array[14] = tmp; + tmp = vminf(array[15], array[31]); + array[31] = vmaxf(array[15], array[31]); + array[15] = tmp; + tmp = vminf(array[32], array[48]); + array[48] = vmaxf(array[32], array[48]); + array[32] = tmp; + tmp = vminf(array[33], array[49]); + array[49] = vmaxf(array[33], array[49]); + array[33] = tmp; + tmp = vminf(array[34], array[50]); + array[50] = vmaxf(array[34], array[50]); + array[34] = tmp; + tmp = vminf(array[35], array[51]); + array[51] = vmaxf(array[35], array[51]); + array[35] = tmp; + tmp = vminf(array[36], array[52]); + array[52] = vmaxf(array[36], array[52]); + array[36] = tmp; + tmp = vminf(array[37], array[53]); + array[53] = vmaxf(array[37], array[53]); + array[37] = tmp; + tmp = vminf(array[38], array[54]); + array[54] = vmaxf(array[38], array[54]); + array[38] = tmp; + tmp = vminf(array[39], array[55]); + array[55] = vmaxf(array[39], array[55]); + array[39] = tmp; + tmp = vminf(array[40], array[56]); + array[56] = vmaxf(array[40], array[56]); + array[40] = tmp; + tmp = vminf(array[41], array[57]); + array[57] = vmaxf(array[41], array[57]); + array[41] = tmp; + tmp = vminf(array[42], array[58]); + array[58] = vmaxf(array[42], array[58]); + array[42] = tmp; + tmp = vminf(array[43], array[59]); + array[59] = vmaxf(array[43], array[59]); + array[43] = tmp; + tmp = vminf(array[44], array[60]); + array[60] = vmaxf(array[44], array[60]); + array[44] = tmp; + tmp = vminf(array[45], array[61]); + array[61] = vmaxf(array[45], array[61]); + array[45] = tmp; + tmp = vminf(array[46], array[62]); + array[62] = vmaxf(array[46], array[62]); + array[46] = tmp; + tmp = vminf(array[47], array[63]); + array[63] = vmaxf(array[47], array[63]); + array[47] = tmp; + tmp = vminf(array[64], array[80]); + array[80] = vmaxf(array[64], array[80]); + array[64] = tmp; + tmp = vminf(array[16], array[64]); + array[64] = vmaxf(array[16], array[64]); + array[16] = tmp; + tmp = vminf(array[17], array[65]); + array[65] = vmaxf(array[17], array[65]); + array[17] = tmp; + tmp = vminf(array[18], array[66]); + array[66] = vmaxf(array[18], array[66]); + array[18] = tmp; + tmp = vminf(array[19], array[67]); + array[67] = vmaxf(array[19], array[67]); + array[19] = tmp; + tmp = vminf(array[20], array[68]); + array[68] = vmaxf(array[20], array[68]); + array[20] = tmp; + tmp = vminf(array[21], array[69]); + array[69] = vmaxf(array[21], array[69]); + array[21] = tmp; + tmp = vminf(array[22], array[70]); + array[70] = vmaxf(array[22], array[70]); + array[22] = tmp; + tmp = vminf(array[23], array[71]); + array[71] = vmaxf(array[23], array[71]); + array[23] = tmp; + tmp = vminf(array[24], array[72]); + array[72] = vmaxf(array[24], array[72]); + array[24] = tmp; + tmp = vminf(array[25], array[73]); + array[73] = vmaxf(array[25], array[73]); + array[25] = tmp; + tmp = vminf(array[26], array[74]); + array[74] = vmaxf(array[26], array[74]); + array[26] = tmp; + tmp = vminf(array[27], array[75]); + array[75] = vmaxf(array[27], array[75]); + array[27] = tmp; + tmp = vminf(array[28], array[76]); + array[76] = vmaxf(array[28], array[76]); + array[28] = tmp; + tmp = vminf(array[29], array[77]); + array[77] = vmaxf(array[29], array[77]); + array[29] = tmp; + tmp = vminf(array[30], array[78]); + array[78] = vmaxf(array[30], array[78]); + array[30] = tmp; + tmp = vminf(array[31], array[79]); + array[79] = vmaxf(array[31], array[79]); + array[31] = tmp; + tmp = vminf(array[16], array[32]); + array[32] = vmaxf(array[16], array[32]); + array[16] = tmp; + tmp = vminf(array[17], array[33]); + array[33] = vmaxf(array[17], array[33]); + array[17] = tmp; + tmp = vminf(array[18], array[34]); + array[34] = vmaxf(array[18], array[34]); + array[18] = tmp; + tmp = vminf(array[19], array[35]); + array[35] = vmaxf(array[19], array[35]); + array[19] = tmp; + tmp = vminf(array[20], array[36]); + array[36] = vmaxf(array[20], array[36]); + array[20] = tmp; + tmp = vminf(array[21], array[37]); + array[37] = vmaxf(array[21], array[37]); + array[21] = tmp; + tmp = vminf(array[22], array[38]); + array[38] = vmaxf(array[22], array[38]); + array[22] = tmp; + tmp = vminf(array[23], array[39]); + array[39] = vmaxf(array[23], array[39]); + array[23] = tmp; + tmp = vminf(array[24], array[40]); + array[40] = vmaxf(array[24], array[40]); + array[24] = tmp; + tmp = vminf(array[25], array[41]); + array[41] = vmaxf(array[25], array[41]); + array[25] = tmp; + tmp = vminf(array[26], array[42]); + array[42] = vmaxf(array[26], array[42]); + array[26] = tmp; + tmp = vminf(array[27], array[43]); + array[43] = vmaxf(array[27], array[43]); + array[27] = tmp; + tmp = vminf(array[28], array[44]); + array[44] = vmaxf(array[28], array[44]); + array[28] = tmp; + tmp = vminf(array[29], array[45]); + array[45] = vmaxf(array[29], array[45]); + array[29] = tmp; + tmp = vminf(array[30], array[46]); + array[46] = vmaxf(array[30], array[46]); + array[30] = tmp; + tmp = vminf(array[31], array[47]); + array[47] = vmaxf(array[31], array[47]); + array[31] = tmp; + tmp = vminf(array[48], array[64]); + array[64] = vmaxf(array[48], array[64]); + array[48] = tmp; + tmp = vminf(array[49], array[65]); + array[65] = vmaxf(array[49], array[65]); + array[49] = tmp; + tmp = vminf(array[50], array[66]); + array[66] = vmaxf(array[50], array[66]); + array[50] = tmp; + tmp = vminf(array[51], array[67]); + array[67] = vmaxf(array[51], array[67]); + array[51] = tmp; + tmp = vminf(array[52], array[68]); + array[68] = vmaxf(array[52], array[68]); + array[52] = tmp; + tmp = vminf(array[53], array[69]); + array[69] = vmaxf(array[53], array[69]); + array[53] = tmp; + tmp = vminf(array[54], array[70]); + array[70] = vmaxf(array[54], array[70]); + array[54] = tmp; + tmp = vminf(array[55], array[71]); + array[71] = vmaxf(array[55], array[71]); + array[55] = tmp; + tmp = vminf(array[56], array[72]); + array[72] = vmaxf(array[56], array[72]); + array[56] = tmp; + tmp = vminf(array[57], array[73]); + array[73] = vmaxf(array[57], array[73]); + array[57] = tmp; + tmp = vminf(array[58], array[74]); + array[74] = vmaxf(array[58], array[74]); + array[58] = tmp; + tmp = vminf(array[59], array[75]); + array[75] = vmaxf(array[59], array[75]); + array[59] = tmp; + tmp = vminf(array[60], array[76]); + array[76] = vmaxf(array[60], array[76]); + array[60] = tmp; + tmp = vminf(array[61], array[77]); + array[77] = vmaxf(array[61], array[77]); + array[61] = tmp; + tmp = vminf(array[62], array[78]); + array[78] = vmaxf(array[62], array[78]); + array[62] = tmp; + tmp = vminf(array[63], array[79]); + array[79] = vmaxf(array[63], array[79]); + array[63] = tmp; + tmp = vminf(array[0], array[8]); + array[8] = vmaxf(array[0], array[8]); + array[0] = tmp; + tmp = vminf(array[1], array[9]); + array[9] = vmaxf(array[1], array[9]); + array[1] = tmp; + tmp = vminf(array[2], array[10]); + array[10] = vmaxf(array[2], array[10]); + array[2] = tmp; + tmp = vminf(array[3], array[11]); + array[11] = vmaxf(array[3], array[11]); + array[3] = tmp; + tmp = vminf(array[4], array[12]); + array[12] = vmaxf(array[4], array[12]); + array[4] = tmp; + tmp = vminf(array[5], array[13]); + array[13] = vmaxf(array[5], array[13]); + array[5] = tmp; + tmp = vminf(array[6], array[14]); + array[14] = vmaxf(array[6], array[14]); + array[6] = tmp; + tmp = vminf(array[7], array[15]); + array[15] = vmaxf(array[7], array[15]); + array[7] = tmp; + tmp = vminf(array[16], array[24]); + array[24] = vmaxf(array[16], array[24]); + array[16] = tmp; + tmp = vminf(array[17], array[25]); + array[25] = vmaxf(array[17], array[25]); + array[17] = tmp; + tmp = vminf(array[18], array[26]); + array[26] = vmaxf(array[18], array[26]); + array[18] = tmp; + tmp = vminf(array[19], array[27]); + array[27] = vmaxf(array[19], array[27]); + array[19] = tmp; + tmp = vminf(array[20], array[28]); + array[28] = vmaxf(array[20], array[28]); + array[20] = tmp; + tmp = vminf(array[21], array[29]); + array[29] = vmaxf(array[21], array[29]); + array[21] = tmp; + tmp = vminf(array[22], array[30]); + array[30] = vmaxf(array[22], array[30]); + array[22] = tmp; + tmp = vminf(array[23], array[31]); + array[31] = vmaxf(array[23], array[31]); + array[23] = tmp; + tmp = vminf(array[32], array[40]); + array[40] = vmaxf(array[32], array[40]); + array[32] = tmp; + tmp = vminf(array[33], array[41]); + array[41] = vmaxf(array[33], array[41]); + array[33] = tmp; + tmp = vminf(array[34], array[42]); + array[42] = vmaxf(array[34], array[42]); + array[34] = tmp; + tmp = vminf(array[35], array[43]); + array[43] = vmaxf(array[35], array[43]); + array[35] = tmp; + tmp = vminf(array[36], array[44]); + array[44] = vmaxf(array[36], array[44]); + array[36] = tmp; + tmp = vminf(array[37], array[45]); + array[45] = vmaxf(array[37], array[45]); + array[37] = tmp; + tmp = vminf(array[38], array[46]); + array[46] = vmaxf(array[38], array[46]); + array[38] = tmp; + tmp = vminf(array[39], array[47]); + array[47] = vmaxf(array[39], array[47]); + array[39] = tmp; + tmp = vminf(array[48], array[56]); + array[56] = vmaxf(array[48], array[56]); + array[48] = tmp; + tmp = vminf(array[49], array[57]); + array[57] = vmaxf(array[49], array[57]); + array[49] = tmp; + tmp = vminf(array[50], array[58]); + array[58] = vmaxf(array[50], array[58]); + array[50] = tmp; + tmp = vminf(array[51], array[59]); + array[59] = vmaxf(array[51], array[59]); + array[51] = tmp; + tmp = vminf(array[52], array[60]); + array[60] = vmaxf(array[52], array[60]); + array[52] = tmp; + tmp = vminf(array[53], array[61]); + array[61] = vmaxf(array[53], array[61]); + array[53] = tmp; + tmp = vminf(array[54], array[62]); + array[62] = vmaxf(array[54], array[62]); + array[54] = tmp; + tmp = vminf(array[55], array[63]); + array[63] = vmaxf(array[55], array[63]); + array[55] = tmp; + tmp = vminf(array[64], array[72]); + array[72] = vmaxf(array[64], array[72]); + array[64] = tmp; + tmp = vminf(array[65], array[73]); + array[73] = vmaxf(array[65], array[73]); + array[65] = tmp; + tmp = vminf(array[66], array[74]); + array[74] = vmaxf(array[66], array[74]); + array[66] = tmp; + tmp = vminf(array[67], array[75]); + array[75] = vmaxf(array[67], array[75]); + array[67] = tmp; + tmp = vminf(array[68], array[76]); + array[76] = vmaxf(array[68], array[76]); + array[68] = tmp; + tmp = vminf(array[69], array[77]); + array[77] = vmaxf(array[69], array[77]); + array[69] = tmp; + tmp = vminf(array[70], array[78]); + array[78] = vmaxf(array[70], array[78]); + array[70] = tmp; + tmp = vminf(array[71], array[79]); + array[79] = vmaxf(array[71], array[79]); + array[71] = tmp; + tmp = vminf(array[8], array[64]); + array[64] = vmaxf(array[8], array[64]); + array[8] = tmp; + tmp = vminf(array[9], array[65]); + array[65] = vmaxf(array[9], array[65]); + array[9] = tmp; + tmp = vminf(array[10], array[66]); + array[66] = vmaxf(array[10], array[66]); + array[10] = tmp; + tmp = vminf(array[11], array[67]); + array[67] = vmaxf(array[11], array[67]); + array[11] = tmp; + tmp = vminf(array[12], array[68]); + array[68] = vmaxf(array[12], array[68]); + array[12] = tmp; + tmp = vminf(array[13], array[69]); + array[69] = vmaxf(array[13], array[69]); + array[13] = tmp; + tmp = vminf(array[14], array[70]); + array[70] = vmaxf(array[14], array[70]); + array[14] = tmp; + tmp = vminf(array[15], array[71]); + array[71] = vmaxf(array[15], array[71]); + array[15] = tmp; + tmp = vminf(array[24], array[80]); + array[80] = vmaxf(array[24], array[80]); + array[24] = tmp; + tmp = vminf(array[8], array[32]); + array[32] = vmaxf(array[8], array[32]); + array[8] = tmp; + tmp = vminf(array[9], array[33]); + array[33] = vmaxf(array[9], array[33]); + array[9] = tmp; + tmp = vminf(array[10], array[34]); + array[34] = vmaxf(array[10], array[34]); + array[10] = tmp; + tmp = vminf(array[11], array[35]); + array[35] = vmaxf(array[11], array[35]); + array[11] = tmp; + tmp = vminf(array[12], array[36]); + array[36] = vmaxf(array[12], array[36]); + array[12] = tmp; + tmp = vminf(array[13], array[37]); + array[37] = vmaxf(array[13], array[37]); + array[13] = tmp; + tmp = vminf(array[14], array[38]); + array[38] = vmaxf(array[14], array[38]); + array[14] = tmp; + tmp = vminf(array[15], array[39]); + array[39] = vmaxf(array[15], array[39]); + array[15] = tmp; + tmp = vminf(array[24], array[48]); + array[48] = vmaxf(array[24], array[48]); + array[24] = tmp; + tmp = vminf(array[25], array[49]); + array[49] = vmaxf(array[25], array[49]); + array[25] = tmp; + tmp = vminf(array[26], array[50]); + array[50] = vmaxf(array[26], array[50]); + array[26] = tmp; + tmp = vminf(array[27], array[51]); + array[51] = vmaxf(array[27], array[51]); + array[27] = tmp; + tmp = vminf(array[28], array[52]); + array[52] = vmaxf(array[28], array[52]); + array[28] = tmp; + tmp = vminf(array[29], array[53]); + array[53] = vmaxf(array[29], array[53]); + array[29] = tmp; + tmp = vminf(array[30], array[54]); + array[54] = vmaxf(array[30], array[54]); + array[30] = tmp; + tmp = vminf(array[31], array[55]); + array[55] = vmaxf(array[31], array[55]); + array[31] = tmp; + tmp = vminf(array[40], array[64]); + array[64] = vmaxf(array[40], array[64]); + array[40] = tmp; + tmp = vminf(array[41], array[65]); + array[65] = vmaxf(array[41], array[65]); + array[41] = tmp; + tmp = vminf(array[42], array[66]); + array[66] = vmaxf(array[42], array[66]); + array[42] = tmp; + tmp = vminf(array[43], array[67]); + array[67] = vmaxf(array[43], array[67]); + array[43] = tmp; + tmp = vminf(array[44], array[68]); + array[68] = vmaxf(array[44], array[68]); + array[44] = tmp; + tmp = vminf(array[45], array[69]); + array[69] = vmaxf(array[45], array[69]); + array[45] = tmp; + tmp = vminf(array[46], array[70]); + array[70] = vmaxf(array[46], array[70]); + array[46] = tmp; + tmp = vminf(array[47], array[71]); + array[71] = vmaxf(array[47], array[71]); + array[47] = tmp; + tmp = vminf(array[56], array[80]); + array[80] = vmaxf(array[56], array[80]); + array[56] = tmp; + tmp = vminf(array[8], array[16]); + array[16] = vmaxf(array[8], array[16]); + array[8] = tmp; + tmp = vminf(array[9], array[17]); + array[17] = vmaxf(array[9], array[17]); + array[9] = tmp; + tmp = vminf(array[10], array[18]); + array[18] = vmaxf(array[10], array[18]); + array[10] = tmp; + tmp = vminf(array[11], array[19]); + array[19] = vmaxf(array[11], array[19]); + array[11] = tmp; + tmp = vminf(array[12], array[20]); + array[20] = vmaxf(array[12], array[20]); + array[12] = tmp; + tmp = vminf(array[13], array[21]); + array[21] = vmaxf(array[13], array[21]); + array[13] = tmp; + tmp = vminf(array[14], array[22]); + array[22] = vmaxf(array[14], array[22]); + array[14] = tmp; + tmp = vminf(array[15], array[23]); + array[23] = vmaxf(array[15], array[23]); + array[15] = tmp; + tmp = vminf(array[24], array[32]); + array[32] = vmaxf(array[24], array[32]); + array[24] = tmp; + tmp = vminf(array[25], array[33]); + array[33] = vmaxf(array[25], array[33]); + array[25] = tmp; + tmp = vminf(array[26], array[34]); + array[34] = vmaxf(array[26], array[34]); + array[26] = tmp; + tmp = vminf(array[27], array[35]); + array[35] = vmaxf(array[27], array[35]); + array[27] = tmp; + tmp = vminf(array[28], array[36]); + array[36] = vmaxf(array[28], array[36]); + array[28] = tmp; + tmp = vminf(array[29], array[37]); + array[37] = vmaxf(array[29], array[37]); + array[29] = tmp; + tmp = vminf(array[30], array[38]); + array[38] = vmaxf(array[30], array[38]); + array[30] = tmp; + tmp = vminf(array[31], array[39]); + array[39] = vmaxf(array[31], array[39]); + array[31] = tmp; + tmp = vminf(array[40], array[48]); + array[48] = vmaxf(array[40], array[48]); + array[40] = tmp; + tmp = vminf(array[41], array[49]); + array[49] = vmaxf(array[41], array[49]); + array[41] = tmp; + tmp = vminf(array[42], array[50]); + array[50] = vmaxf(array[42], array[50]); + array[42] = tmp; + tmp = vminf(array[43], array[51]); + array[51] = vmaxf(array[43], array[51]); + array[43] = tmp; + tmp = vminf(array[44], array[52]); + array[52] = vmaxf(array[44], array[52]); + array[44] = tmp; + tmp = vminf(array[45], array[53]); + array[53] = vmaxf(array[45], array[53]); + array[45] = tmp; + tmp = vminf(array[46], array[54]); + array[54] = vmaxf(array[46], array[54]); + array[46] = tmp; + tmp = vminf(array[47], array[55]); + array[55] = vmaxf(array[47], array[55]); + array[47] = tmp; + tmp = vminf(array[56], array[64]); + array[64] = vmaxf(array[56], array[64]); + array[56] = tmp; + tmp = vminf(array[57], array[65]); + array[65] = vmaxf(array[57], array[65]); + array[57] = tmp; + tmp = vminf(array[58], array[66]); + array[66] = vmaxf(array[58], array[66]); + array[58] = tmp; + tmp = vminf(array[59], array[67]); + array[67] = vmaxf(array[59], array[67]); + array[59] = tmp; + tmp = vminf(array[60], array[68]); + array[68] = vmaxf(array[60], array[68]); + array[60] = tmp; + tmp = vminf(array[61], array[69]); + array[69] = vmaxf(array[61], array[69]); + array[61] = tmp; + tmp = vminf(array[62], array[70]); + array[70] = vmaxf(array[62], array[70]); + array[62] = tmp; + tmp = vminf(array[63], array[71]); + array[71] = vmaxf(array[63], array[71]); + array[63] = tmp; + tmp = vminf(array[72], array[80]); + array[80] = vmaxf(array[72], array[80]); + array[72] = tmp; + tmp = vminf(array[0], array[4]); + array[4] = vmaxf(array[0], array[4]); + array[0] = tmp; + tmp = vminf(array[1], array[5]); + array[5] = vmaxf(array[1], array[5]); + array[1] = tmp; + tmp = vminf(array[2], array[6]); + array[6] = vmaxf(array[2], array[6]); + array[2] = tmp; + tmp = vminf(array[3], array[7]); + array[7] = vmaxf(array[3], array[7]); + array[3] = tmp; + tmp = vminf(array[8], array[12]); + array[12] = vmaxf(array[8], array[12]); + array[8] = tmp; + tmp = vminf(array[9], array[13]); + array[13] = vmaxf(array[9], array[13]); + array[9] = tmp; + tmp = vminf(array[10], array[14]); + array[14] = vmaxf(array[10], array[14]); + array[10] = tmp; + tmp = vminf(array[11], array[15]); + array[15] = vmaxf(array[11], array[15]); + array[11] = tmp; + tmp = vminf(array[16], array[20]); + array[20] = vmaxf(array[16], array[20]); + array[16] = tmp; + tmp = vminf(array[17], array[21]); + array[21] = vmaxf(array[17], array[21]); + array[17] = tmp; + tmp = vminf(array[18], array[22]); + array[22] = vmaxf(array[18], array[22]); + array[18] = tmp; + tmp = vminf(array[19], array[23]); + array[23] = vmaxf(array[19], array[23]); + array[19] = tmp; + tmp = vminf(array[24], array[28]); + array[28] = vmaxf(array[24], array[28]); + array[24] = tmp; + tmp = vminf(array[25], array[29]); + array[29] = vmaxf(array[25], array[29]); + array[25] = tmp; + tmp = vminf(array[26], array[30]); + array[30] = vmaxf(array[26], array[30]); + array[26] = tmp; + tmp = vminf(array[27], array[31]); + array[31] = vmaxf(array[27], array[31]); + array[27] = tmp; + tmp = vminf(array[32], array[36]); + array[36] = vmaxf(array[32], array[36]); + array[32] = tmp; + tmp = vminf(array[33], array[37]); + array[37] = vmaxf(array[33], array[37]); + array[33] = tmp; + tmp = vminf(array[34], array[38]); + array[38] = vmaxf(array[34], array[38]); + array[34] = tmp; + tmp = vminf(array[35], array[39]); + array[39] = vmaxf(array[35], array[39]); + array[35] = tmp; + tmp = vminf(array[40], array[44]); + array[44] = vmaxf(array[40], array[44]); + array[40] = tmp; + tmp = vminf(array[41], array[45]); + array[45] = vmaxf(array[41], array[45]); + array[41] = tmp; + tmp = vminf(array[42], array[46]); + array[46] = vmaxf(array[42], array[46]); + array[42] = tmp; + tmp = vminf(array[43], array[47]); + array[47] = vmaxf(array[43], array[47]); + array[43] = tmp; + tmp = vminf(array[48], array[52]); + array[52] = vmaxf(array[48], array[52]); + array[48] = tmp; + tmp = vminf(array[49], array[53]); + array[53] = vmaxf(array[49], array[53]); + array[49] = tmp; + tmp = vminf(array[50], array[54]); + array[54] = vmaxf(array[50], array[54]); + array[50] = tmp; + tmp = vminf(array[51], array[55]); + array[55] = vmaxf(array[51], array[55]); + array[51] = tmp; + tmp = vminf(array[56], array[60]); + array[60] = vmaxf(array[56], array[60]); + array[56] = tmp; + tmp = vminf(array[57], array[61]); + array[61] = vmaxf(array[57], array[61]); + array[57] = tmp; + tmp = vminf(array[58], array[62]); + array[62] = vmaxf(array[58], array[62]); + array[58] = tmp; + tmp = vminf(array[59], array[63]); + array[63] = vmaxf(array[59], array[63]); + array[59] = tmp; + tmp = vminf(array[64], array[68]); + array[68] = vmaxf(array[64], array[68]); + array[64] = tmp; + tmp = vminf(array[65], array[69]); + array[69] = vmaxf(array[65], array[69]); + array[65] = tmp; + tmp = vminf(array[66], array[70]); + array[70] = vmaxf(array[66], array[70]); + array[66] = tmp; + tmp = vminf(array[67], array[71]); + array[71] = vmaxf(array[67], array[71]); + array[67] = tmp; + tmp = vminf(array[72], array[76]); + array[76] = vmaxf(array[72], array[76]); + array[72] = tmp; + tmp = vminf(array[73], array[77]); + array[77] = vmaxf(array[73], array[77]); + array[73] = tmp; + tmp = vminf(array[74], array[78]); + array[78] = vmaxf(array[74], array[78]); + array[74] = tmp; + tmp = vminf(array[75], array[79]); + array[79] = vmaxf(array[75], array[79]); + array[75] = tmp; + tmp = vminf(array[4], array[64]); + array[64] = vmaxf(array[4], array[64]); + array[4] = tmp; + tmp = vminf(array[5], array[65]); + array[65] = vmaxf(array[5], array[65]); + array[5] = tmp; + tmp = vminf(array[6], array[66]); + array[66] = vmaxf(array[6], array[66]); + array[6] = tmp; + tmp = vminf(array[7], array[67]); + array[67] = vmaxf(array[7], array[67]); + array[7] = tmp; + tmp = vminf(array[12], array[72]); + array[72] = vmaxf(array[12], array[72]); + array[12] = tmp; + tmp = vminf(array[13], array[73]); + array[73] = vmaxf(array[13], array[73]); + array[13] = tmp; + tmp = vminf(array[14], array[74]); + array[74] = vmaxf(array[14], array[74]); + array[14] = tmp; + tmp = vminf(array[15], array[75]); + array[75] = vmaxf(array[15], array[75]); + array[15] = tmp; + tmp = vminf(array[20], array[80]); + array[80] = vmaxf(array[20], array[80]); + array[20] = tmp; + tmp = vminf(array[4], array[32]); + array[32] = vmaxf(array[4], array[32]); + array[4] = tmp; + tmp = vminf(array[5], array[33]); + array[33] = vmaxf(array[5], array[33]); + array[5] = tmp; + tmp = vminf(array[6], array[34]); + array[34] = vmaxf(array[6], array[34]); + array[6] = tmp; + tmp = vminf(array[7], array[35]); + array[35] = vmaxf(array[7], array[35]); + array[7] = tmp; + tmp = vminf(array[12], array[40]); + array[40] = vmaxf(array[12], array[40]); + array[12] = tmp; + tmp = vminf(array[13], array[41]); + array[41] = vmaxf(array[13], array[41]); + array[13] = tmp; + tmp = vminf(array[14], array[42]); + array[42] = vmaxf(array[14], array[42]); + array[14] = tmp; + tmp = vminf(array[15], array[43]); + array[43] = vmaxf(array[15], array[43]); + array[15] = tmp; + tmp = vminf(array[20], array[48]); + array[48] = vmaxf(array[20], array[48]); + array[20] = tmp; + tmp = vminf(array[21], array[49]); + array[49] = vmaxf(array[21], array[49]); + array[21] = tmp; + tmp = vminf(array[22], array[50]); + array[50] = vmaxf(array[22], array[50]); + array[22] = tmp; + tmp = vminf(array[23], array[51]); + array[51] = vmaxf(array[23], array[51]); + array[23] = tmp; + tmp = vminf(array[28], array[56]); + array[56] = vmaxf(array[28], array[56]); + array[28] = tmp; + tmp = vminf(array[29], array[57]); + array[57] = vmaxf(array[29], array[57]); + array[29] = tmp; + tmp = vminf(array[30], array[58]); + array[58] = vmaxf(array[30], array[58]); + array[30] = tmp; + tmp = vminf(array[31], array[59]); + array[59] = vmaxf(array[31], array[59]); + array[31] = tmp; + tmp = vminf(array[36], array[64]); + array[64] = vmaxf(array[36], array[64]); + array[36] = tmp; + tmp = vminf(array[37], array[65]); + array[65] = vmaxf(array[37], array[65]); + array[37] = tmp; + tmp = vminf(array[38], array[66]); + array[66] = vmaxf(array[38], array[66]); + array[38] = tmp; + tmp = vminf(array[39], array[67]); + array[67] = vmaxf(array[39], array[67]); + array[39] = tmp; + tmp = vminf(array[44], array[72]); + array[72] = vmaxf(array[44], array[72]); + array[44] = tmp; + tmp = vminf(array[45], array[73]); + array[73] = vmaxf(array[45], array[73]); + array[45] = tmp; + tmp = vminf(array[46], array[74]); + array[74] = vmaxf(array[46], array[74]); + array[46] = tmp; + tmp = vminf(array[47], array[75]); + array[75] = vmaxf(array[47], array[75]); + array[47] = tmp; + tmp = vminf(array[52], array[80]); + array[80] = vmaxf(array[52], array[80]); + array[52] = tmp; + tmp = vminf(array[4], array[16]); + array[16] = vmaxf(array[4], array[16]); + array[4] = tmp; + tmp = vminf(array[5], array[17]); + array[17] = vmaxf(array[5], array[17]); + array[5] = tmp; + tmp = vminf(array[6], array[18]); + array[18] = vmaxf(array[6], array[18]); + array[6] = tmp; + tmp = vminf(array[7], array[19]); + array[19] = vmaxf(array[7], array[19]); + array[7] = tmp; + tmp = vminf(array[12], array[24]); + array[24] = vmaxf(array[12], array[24]); + array[12] = tmp; + tmp = vminf(array[13], array[25]); + array[25] = vmaxf(array[13], array[25]); + array[13] = tmp; + tmp = vminf(array[14], array[26]); + array[26] = vmaxf(array[14], array[26]); + array[14] = tmp; + tmp = vminf(array[15], array[27]); + array[27] = vmaxf(array[15], array[27]); + array[15] = tmp; + tmp = vminf(array[20], array[32]); + array[32] = vmaxf(array[20], array[32]); + array[20] = tmp; + tmp = vminf(array[21], array[33]); + array[33] = vmaxf(array[21], array[33]); + array[21] = tmp; + tmp = vminf(array[22], array[34]); + array[34] = vmaxf(array[22], array[34]); + array[22] = tmp; + tmp = vminf(array[23], array[35]); + array[35] = vmaxf(array[23], array[35]); + array[23] = tmp; + tmp = vminf(array[28], array[40]); + array[40] = vmaxf(array[28], array[40]); + array[28] = tmp; + tmp = vminf(array[29], array[41]); + array[41] = vmaxf(array[29], array[41]); + array[29] = tmp; + tmp = vminf(array[30], array[42]); + array[42] = vmaxf(array[30], array[42]); + array[30] = tmp; + tmp = vminf(array[31], array[43]); + array[43] = vmaxf(array[31], array[43]); + array[31] = tmp; + tmp = vminf(array[36], array[48]); + array[48] = vmaxf(array[36], array[48]); + array[36] = tmp; + tmp = vminf(array[37], array[49]); + array[49] = vmaxf(array[37], array[49]); + array[37] = tmp; + tmp = vminf(array[38], array[50]); + array[50] = vmaxf(array[38], array[50]); + array[38] = tmp; + tmp = vminf(array[39], array[51]); + array[51] = vmaxf(array[39], array[51]); + array[39] = tmp; + tmp = vminf(array[44], array[56]); + array[56] = vmaxf(array[44], array[56]); + array[44] = tmp; + tmp = vminf(array[45], array[57]); + array[57] = vmaxf(array[45], array[57]); + array[45] = tmp; + tmp = vminf(array[46], array[58]); + array[58] = vmaxf(array[46], array[58]); + array[46] = tmp; + tmp = vminf(array[47], array[59]); + array[59] = vmaxf(array[47], array[59]); + array[47] = tmp; + tmp = vminf(array[52], array[64]); + array[64] = vmaxf(array[52], array[64]); + array[52] = tmp; + tmp = vminf(array[53], array[65]); + array[65] = vmaxf(array[53], array[65]); + array[53] = tmp; + tmp = vminf(array[54], array[66]); + array[66] = vmaxf(array[54], array[66]); + array[54] = tmp; + tmp = vminf(array[55], array[67]); + array[67] = vmaxf(array[55], array[67]); + array[55] = tmp; + tmp = vminf(array[60], array[72]); + array[72] = vmaxf(array[60], array[72]); + array[60] = tmp; + tmp = vminf(array[61], array[73]); + array[73] = vmaxf(array[61], array[73]); + array[61] = tmp; + tmp = vminf(array[62], array[74]); + array[74] = vmaxf(array[62], array[74]); + array[62] = tmp; + tmp = vminf(array[63], array[75]); + array[75] = vmaxf(array[63], array[75]); + array[63] = tmp; + tmp = vminf(array[68], array[80]); + array[80] = vmaxf(array[68], array[80]); + array[68] = tmp; + tmp = vminf(array[4], array[8]); + array[8] = vmaxf(array[4], array[8]); + array[4] = tmp; + tmp = vminf(array[5], array[9]); + array[9] = vmaxf(array[5], array[9]); + array[5] = tmp; + tmp = vminf(array[6], array[10]); + array[10] = vmaxf(array[6], array[10]); + array[6] = tmp; + tmp = vminf(array[7], array[11]); + array[11] = vmaxf(array[7], array[11]); + array[7] = tmp; + tmp = vminf(array[12], array[16]); + array[16] = vmaxf(array[12], array[16]); + array[12] = tmp; + tmp = vminf(array[13], array[17]); + array[17] = vmaxf(array[13], array[17]); + array[13] = tmp; + tmp = vminf(array[14], array[18]); + array[18] = vmaxf(array[14], array[18]); + array[14] = tmp; + tmp = vminf(array[15], array[19]); + array[19] = vmaxf(array[15], array[19]); + array[15] = tmp; + tmp = vminf(array[20], array[24]); + array[24] = vmaxf(array[20], array[24]); + array[20] = tmp; + tmp = vminf(array[21], array[25]); + array[25] = vmaxf(array[21], array[25]); + array[21] = tmp; + tmp = vminf(array[22], array[26]); + array[26] = vmaxf(array[22], array[26]); + array[22] = tmp; + tmp = vminf(array[23], array[27]); + array[27] = vmaxf(array[23], array[27]); + array[23] = tmp; + tmp = vminf(array[28], array[32]); + array[32] = vmaxf(array[28], array[32]); + array[28] = tmp; + tmp = vminf(array[29], array[33]); + array[33] = vmaxf(array[29], array[33]); + array[29] = tmp; + tmp = vminf(array[30], array[34]); + array[34] = vmaxf(array[30], array[34]); + array[30] = tmp; + tmp = vminf(array[31], array[35]); + array[35] = vmaxf(array[31], array[35]); + array[31] = tmp; + tmp = vminf(array[36], array[40]); + array[40] = vmaxf(array[36], array[40]); + array[36] = tmp; + tmp = vminf(array[37], array[41]); + array[41] = vmaxf(array[37], array[41]); + array[37] = tmp; + tmp = vminf(array[38], array[42]); + array[42] = vmaxf(array[38], array[42]); + array[38] = tmp; + tmp = vminf(array[39], array[43]); + array[43] = vmaxf(array[39], array[43]); + array[39] = tmp; + tmp = vminf(array[44], array[48]); + array[48] = vmaxf(array[44], array[48]); + array[44] = tmp; + tmp = vminf(array[45], array[49]); + array[49] = vmaxf(array[45], array[49]); + array[45] = tmp; + tmp = vminf(array[46], array[50]); + array[50] = vmaxf(array[46], array[50]); + array[46] = tmp; + tmp = vminf(array[47], array[51]); + array[51] = vmaxf(array[47], array[51]); + array[47] = tmp; + tmp = vminf(array[52], array[56]); + array[56] = vmaxf(array[52], array[56]); + array[52] = tmp; + tmp = vminf(array[53], array[57]); + array[57] = vmaxf(array[53], array[57]); + array[53] = tmp; + tmp = vminf(array[54], array[58]); + array[58] = vmaxf(array[54], array[58]); + array[54] = tmp; + tmp = vminf(array[55], array[59]); + array[59] = vmaxf(array[55], array[59]); + array[55] = tmp; + tmp = vminf(array[60], array[64]); + array[64] = vmaxf(array[60], array[64]); + array[60] = tmp; + tmp = vminf(array[61], array[65]); + array[65] = vmaxf(array[61], array[65]); + array[61] = tmp; + tmp = vminf(array[62], array[66]); + array[66] = vmaxf(array[62], array[66]); + array[62] = tmp; + tmp = vminf(array[63], array[67]); + array[67] = vmaxf(array[63], array[67]); + array[63] = tmp; + tmp = vminf(array[68], array[72]); + array[72] = vmaxf(array[68], array[72]); + array[68] = tmp; + tmp = vminf(array[69], array[73]); + array[73] = vmaxf(array[69], array[73]); + array[69] = tmp; + tmp = vminf(array[70], array[74]); + array[74] = vmaxf(array[70], array[74]); + array[70] = tmp; + tmp = vminf(array[71], array[75]); + array[75] = vmaxf(array[71], array[75]); + array[71] = tmp; + tmp = vminf(array[76], array[80]); + array[80] = vmaxf(array[76], array[80]); + array[76] = tmp; + tmp = vminf(array[0], array[2]); + array[2] = vmaxf(array[0], array[2]); + array[0] = tmp; + tmp = vminf(array[1], array[3]); + array[3] = vmaxf(array[1], array[3]); + array[1] = tmp; + tmp = vminf(array[4], array[6]); + array[6] = vmaxf(array[4], array[6]); + array[4] = tmp; + tmp = vminf(array[5], array[7]); + array[7] = vmaxf(array[5], array[7]); + array[5] = tmp; + tmp = vminf(array[8], array[10]); + array[10] = vmaxf(array[8], array[10]); + array[8] = tmp; + tmp = vminf(array[9], array[11]); + array[11] = vmaxf(array[9], array[11]); + array[9] = tmp; + tmp = vminf(array[12], array[14]); + array[14] = vmaxf(array[12], array[14]); + array[12] = tmp; + tmp = vminf(array[13], array[15]); + array[15] = vmaxf(array[13], array[15]); + array[13] = tmp; + tmp = vminf(array[16], array[18]); + array[18] = vmaxf(array[16], array[18]); + array[16] = tmp; + tmp = vminf(array[17], array[19]); + array[19] = vmaxf(array[17], array[19]); + array[17] = tmp; + tmp = vminf(array[20], array[22]); + array[22] = vmaxf(array[20], array[22]); + array[20] = tmp; + tmp = vminf(array[21], array[23]); + array[23] = vmaxf(array[21], array[23]); + array[21] = tmp; + tmp = vminf(array[24], array[26]); + array[26] = vmaxf(array[24], array[26]); + array[24] = tmp; + tmp = vminf(array[25], array[27]); + array[27] = vmaxf(array[25], array[27]); + array[25] = tmp; + tmp = vminf(array[28], array[30]); + array[30] = vmaxf(array[28], array[30]); + array[28] = tmp; + tmp = vminf(array[29], array[31]); + array[31] = vmaxf(array[29], array[31]); + array[29] = tmp; + tmp = vminf(array[32], array[34]); + array[34] = vmaxf(array[32], array[34]); + array[32] = tmp; + tmp = vminf(array[33], array[35]); + array[35] = vmaxf(array[33], array[35]); + array[33] = tmp; + tmp = vminf(array[36], array[38]); + array[38] = vmaxf(array[36], array[38]); + array[36] = tmp; + tmp = vminf(array[37], array[39]); + array[39] = vmaxf(array[37], array[39]); + array[37] = tmp; + tmp = vminf(array[40], array[42]); + array[42] = vmaxf(array[40], array[42]); + array[40] = tmp; + tmp = vminf(array[41], array[43]); + array[43] = vmaxf(array[41], array[43]); + array[41] = tmp; + tmp = vminf(array[44], array[46]); + array[46] = vmaxf(array[44], array[46]); + array[44] = tmp; + tmp = vminf(array[45], array[47]); + array[47] = vmaxf(array[45], array[47]); + array[45] = tmp; + tmp = vminf(array[48], array[50]); + array[50] = vmaxf(array[48], array[50]); + array[48] = tmp; + tmp = vminf(array[49], array[51]); + array[51] = vmaxf(array[49], array[51]); + array[49] = tmp; + tmp = vminf(array[52], array[54]); + array[54] = vmaxf(array[52], array[54]); + array[52] = tmp; + tmp = vminf(array[53], array[55]); + array[55] = vmaxf(array[53], array[55]); + array[53] = tmp; + tmp = vminf(array[56], array[58]); + array[58] = vmaxf(array[56], array[58]); + array[56] = tmp; + tmp = vminf(array[57], array[59]); + array[59] = vmaxf(array[57], array[59]); + array[57] = tmp; + tmp = vminf(array[60], array[62]); + array[62] = vmaxf(array[60], array[62]); + array[60] = tmp; + tmp = vminf(array[61], array[63]); + array[63] = vmaxf(array[61], array[63]); + array[61] = tmp; + tmp = vminf(array[64], array[66]); + array[66] = vmaxf(array[64], array[66]); + array[64] = tmp; + tmp = vminf(array[65], array[67]); + array[67] = vmaxf(array[65], array[67]); + array[65] = tmp; + tmp = vminf(array[68], array[70]); + array[70] = vmaxf(array[68], array[70]); + array[68] = tmp; + tmp = vminf(array[69], array[71]); + array[71] = vmaxf(array[69], array[71]); + array[69] = tmp; + tmp = vminf(array[72], array[74]); + array[74] = vmaxf(array[72], array[74]); + array[72] = tmp; + tmp = vminf(array[73], array[75]); + array[75] = vmaxf(array[73], array[75]); + array[73] = tmp; + tmp = vminf(array[76], array[78]); + array[78] = vmaxf(array[76], array[78]); + array[76] = tmp; + tmp = vminf(array[77], array[79]); + array[79] = vmaxf(array[77], array[79]); + array[77] = tmp; + tmp = vminf(array[2], array[64]); + array[64] = vmaxf(array[2], array[64]); + array[2] = tmp; + tmp = vminf(array[3], array[65]); + array[65] = vmaxf(array[3], array[65]); + array[3] = tmp; + tmp = vminf(array[6], array[68]); + array[68] = vmaxf(array[6], array[68]); + array[6] = tmp; + tmp = vminf(array[7], array[69]); + array[69] = vmaxf(array[7], array[69]); + array[7] = tmp; + tmp = vminf(array[10], array[72]); + array[72] = vmaxf(array[10], array[72]); + array[10] = tmp; + tmp = vminf(array[11], array[73]); + array[73] = vmaxf(array[11], array[73]); + array[11] = tmp; + tmp = vminf(array[14], array[76]); + array[76] = vmaxf(array[14], array[76]); + array[14] = tmp; + tmp = vminf(array[15], array[77]); + array[77] = vmaxf(array[15], array[77]); + array[15] = tmp; + tmp = vminf(array[18], array[80]); + array[80] = vmaxf(array[18], array[80]); + array[18] = tmp; + tmp = vminf(array[2], array[32]); + array[32] = vmaxf(array[2], array[32]); + array[2] = tmp; + tmp = vminf(array[3], array[33]); + array[33] = vmaxf(array[3], array[33]); + array[3] = tmp; + tmp = vminf(array[6], array[36]); + array[36] = vmaxf(array[6], array[36]); + array[6] = tmp; + tmp = vminf(array[7], array[37]); + array[37] = vmaxf(array[7], array[37]); + array[7] = tmp; + tmp = vminf(array[10], array[40]); + array[40] = vmaxf(array[10], array[40]); + array[10] = tmp; + tmp = vminf(array[11], array[41]); + array[41] = vmaxf(array[11], array[41]); + array[11] = tmp; + tmp = vminf(array[14], array[44]); + array[44] = vmaxf(array[14], array[44]); + array[14] = tmp; + tmp = vminf(array[15], array[45]); + array[45] = vmaxf(array[15], array[45]); + array[15] = tmp; + tmp = vminf(array[18], array[48]); + array[48] = vmaxf(array[18], array[48]); + array[18] = tmp; + tmp = vminf(array[19], array[49]); + array[49] = vmaxf(array[19], array[49]); + array[19] = tmp; + tmp = vminf(array[22], array[52]); + array[52] = vmaxf(array[22], array[52]); + array[22] = tmp; + tmp = vminf(array[23], array[53]); + array[53] = vmaxf(array[23], array[53]); + array[23] = tmp; + tmp = vminf(array[26], array[56]); + array[56] = vmaxf(array[26], array[56]); + array[26] = tmp; + tmp = vminf(array[27], array[57]); + array[57] = vmaxf(array[27], array[57]); + array[27] = tmp; + tmp = vminf(array[30], array[60]); + array[60] = vmaxf(array[30], array[60]); + array[30] = tmp; + tmp = vminf(array[31], array[61]); + array[61] = vmaxf(array[31], array[61]); + array[31] = tmp; + tmp = vminf(array[34], array[64]); + array[64] = vmaxf(array[34], array[64]); + array[34] = tmp; + tmp = vminf(array[35], array[65]); + array[65] = vmaxf(array[35], array[65]); + array[35] = tmp; + tmp = vminf(array[38], array[68]); + array[68] = vmaxf(array[38], array[68]); + array[38] = tmp; + tmp = vminf(array[39], array[69]); + array[69] = vmaxf(array[39], array[69]); + array[39] = tmp; + tmp = vminf(array[42], array[72]); + array[72] = vmaxf(array[42], array[72]); + array[42] = tmp; + tmp = vminf(array[43], array[73]); + array[73] = vmaxf(array[43], array[73]); + array[43] = tmp; + tmp = vminf(array[46], array[76]); + array[76] = vmaxf(array[46], array[76]); + array[46] = tmp; + tmp = vminf(array[47], array[77]); + array[77] = vmaxf(array[47], array[77]); + array[47] = tmp; + tmp = vminf(array[50], array[80]); + array[80] = vmaxf(array[50], array[80]); + array[50] = tmp; + tmp = vminf(array[2], array[16]); + array[16] = vmaxf(array[2], array[16]); + array[2] = tmp; + tmp = vminf(array[3], array[17]); + array[17] = vmaxf(array[3], array[17]); + array[3] = tmp; + tmp = vminf(array[6], array[20]); + array[20] = vmaxf(array[6], array[20]); + array[6] = tmp; + tmp = vminf(array[7], array[21]); + array[21] = vmaxf(array[7], array[21]); + array[7] = tmp; + tmp = vminf(array[10], array[24]); + array[24] = vmaxf(array[10], array[24]); + array[10] = tmp; + tmp = vminf(array[11], array[25]); + array[25] = vmaxf(array[11], array[25]); + array[11] = tmp; + tmp = vminf(array[14], array[28]); + array[28] = vmaxf(array[14], array[28]); + array[14] = tmp; + tmp = vminf(array[15], array[29]); + array[29] = vmaxf(array[15], array[29]); + array[15] = tmp; + tmp = vminf(array[18], array[32]); + array[32] = vmaxf(array[18], array[32]); + array[18] = tmp; + tmp = vminf(array[19], array[33]); + array[33] = vmaxf(array[19], array[33]); + array[19] = tmp; + tmp = vminf(array[22], array[36]); + array[36] = vmaxf(array[22], array[36]); + array[22] = tmp; + tmp = vminf(array[23], array[37]); + array[37] = vmaxf(array[23], array[37]); + array[23] = tmp; + tmp = vminf(array[26], array[40]); + array[40] = vmaxf(array[26], array[40]); + array[26] = tmp; + tmp = vminf(array[27], array[41]); + array[41] = vmaxf(array[27], array[41]); + array[27] = tmp; + tmp = vminf(array[30], array[44]); + array[44] = vmaxf(array[30], array[44]); + array[30] = tmp; + tmp = vminf(array[31], array[45]); + array[45] = vmaxf(array[31], array[45]); + array[31] = tmp; + tmp = vminf(array[34], array[48]); + array[48] = vmaxf(array[34], array[48]); + array[34] = tmp; + tmp = vminf(array[35], array[49]); + array[49] = vmaxf(array[35], array[49]); + array[35] = tmp; + tmp = vminf(array[38], array[52]); + array[52] = vmaxf(array[38], array[52]); + array[38] = tmp; + tmp = vminf(array[39], array[53]); + array[53] = vmaxf(array[39], array[53]); + array[39] = tmp; + tmp = vminf(array[42], array[56]); + array[56] = vmaxf(array[42], array[56]); + array[42] = tmp; + tmp = vminf(array[43], array[57]); + array[57] = vmaxf(array[43], array[57]); + array[43] = tmp; + tmp = vminf(array[46], array[60]); + array[60] = vmaxf(array[46], array[60]); + array[46] = tmp; + tmp = vminf(array[47], array[61]); + array[61] = vmaxf(array[47], array[61]); + array[47] = tmp; + tmp = vminf(array[50], array[64]); + array[64] = vmaxf(array[50], array[64]); + array[50] = tmp; + tmp = vminf(array[51], array[65]); + array[65] = vmaxf(array[51], array[65]); + array[51] = tmp; + tmp = vminf(array[54], array[68]); + array[68] = vmaxf(array[54], array[68]); + array[54] = tmp; + tmp = vminf(array[55], array[69]); + array[69] = vmaxf(array[55], array[69]); + array[55] = tmp; + tmp = vminf(array[58], array[72]); + array[72] = vmaxf(array[58], array[72]); + array[58] = tmp; + tmp = vminf(array[59], array[73]); + array[73] = vmaxf(array[59], array[73]); + array[59] = tmp; + tmp = vminf(array[62], array[76]); + array[76] = vmaxf(array[62], array[76]); + array[62] = tmp; + tmp = vminf(array[63], array[77]); + array[77] = vmaxf(array[63], array[77]); + array[63] = tmp; + tmp = vminf(array[66], array[80]); + array[80] = vmaxf(array[66], array[80]); + array[66] = tmp; + tmp = vminf(array[2], array[8]); + array[8] = vmaxf(array[2], array[8]); + array[2] = tmp; + tmp = vminf(array[3], array[9]); + array[9] = vmaxf(array[3], array[9]); + array[3] = tmp; + tmp = vminf(array[6], array[12]); + array[12] = vmaxf(array[6], array[12]); + array[6] = tmp; + tmp = vminf(array[7], array[13]); + array[13] = vmaxf(array[7], array[13]); + array[7] = tmp; + tmp = vminf(array[10], array[16]); + array[16] = vmaxf(array[10], array[16]); + array[10] = tmp; + tmp = vminf(array[11], array[17]); + array[17] = vmaxf(array[11], array[17]); + array[11] = tmp; + tmp = vminf(array[14], array[20]); + array[20] = vmaxf(array[14], array[20]); + array[14] = tmp; + tmp = vminf(array[15], array[21]); + array[21] = vmaxf(array[15], array[21]); + array[15] = tmp; + tmp = vminf(array[18], array[24]); + array[24] = vmaxf(array[18], array[24]); + array[18] = tmp; + tmp = vminf(array[19], array[25]); + array[25] = vmaxf(array[19], array[25]); + array[19] = tmp; + tmp = vminf(array[22], array[28]); + array[28] = vmaxf(array[22], array[28]); + array[22] = tmp; + tmp = vminf(array[23], array[29]); + array[29] = vmaxf(array[23], array[29]); + array[23] = tmp; + tmp = vminf(array[26], array[32]); + array[32] = vmaxf(array[26], array[32]); + array[26] = tmp; + tmp = vminf(array[27], array[33]); + array[33] = vmaxf(array[27], array[33]); + array[27] = tmp; + tmp = vminf(array[30], array[36]); + array[36] = vmaxf(array[30], array[36]); + array[30] = tmp; + tmp = vminf(array[31], array[37]); + array[37] = vmaxf(array[31], array[37]); + array[31] = tmp; + tmp = vminf(array[34], array[40]); + array[40] = vmaxf(array[34], array[40]); + array[34] = tmp; + tmp = vminf(array[35], array[41]); + array[41] = vmaxf(array[35], array[41]); + array[35] = tmp; + tmp = vminf(array[38], array[44]); + array[44] = vmaxf(array[38], array[44]); + array[38] = tmp; + tmp = vminf(array[39], array[45]); + array[45] = vmaxf(array[39], array[45]); + array[39] = tmp; + tmp = vminf(array[42], array[48]); + array[48] = vmaxf(array[42], array[48]); + array[42] = tmp; + tmp = vminf(array[43], array[49]); + array[49] = vmaxf(array[43], array[49]); + array[43] = tmp; + tmp = vminf(array[46], array[52]); + array[52] = vmaxf(array[46], array[52]); + array[46] = tmp; + tmp = vminf(array[47], array[53]); + array[53] = vmaxf(array[47], array[53]); + array[47] = tmp; + tmp = vminf(array[50], array[56]); + array[56] = vmaxf(array[50], array[56]); + array[50] = tmp; + tmp = vminf(array[51], array[57]); + array[57] = vmaxf(array[51], array[57]); + array[51] = tmp; + tmp = vminf(array[54], array[60]); + array[60] = vmaxf(array[54], array[60]); + array[54] = tmp; + tmp = vminf(array[55], array[61]); + array[61] = vmaxf(array[55], array[61]); + array[55] = tmp; + tmp = vminf(array[58], array[64]); + array[64] = vmaxf(array[58], array[64]); + array[58] = tmp; + tmp = vminf(array[59], array[65]); + array[65] = vmaxf(array[59], array[65]); + array[59] = tmp; + tmp = vminf(array[62], array[68]); + array[68] = vmaxf(array[62], array[68]); + array[62] = tmp; + tmp = vminf(array[63], array[69]); + array[69] = vmaxf(array[63], array[69]); + array[63] = tmp; + tmp = vminf(array[66], array[72]); + array[72] = vmaxf(array[66], array[72]); + array[66] = tmp; + tmp = vminf(array[67], array[73]); + array[73] = vmaxf(array[67], array[73]); + array[67] = tmp; + tmp = vminf(array[70], array[76]); + array[76] = vmaxf(array[70], array[76]); + array[70] = tmp; + tmp = vminf(array[71], array[77]); + array[77] = vmaxf(array[71], array[77]); + array[71] = tmp; + tmp = vminf(array[74], array[80]); + array[80] = vmaxf(array[74], array[80]); + array[74] = tmp; + tmp = vminf(array[2], array[4]); + array[4] = vmaxf(array[2], array[4]); + array[2] = tmp; + tmp = vminf(array[3], array[5]); + array[5] = vmaxf(array[3], array[5]); + array[3] = tmp; + tmp = vminf(array[6], array[8]); + array[8] = vmaxf(array[6], array[8]); + array[6] = tmp; + tmp = vminf(array[7], array[9]); + array[9] = vmaxf(array[7], array[9]); + array[7] = tmp; + tmp = vminf(array[10], array[12]); + array[12] = vmaxf(array[10], array[12]); + array[10] = tmp; + tmp = vminf(array[11], array[13]); + array[13] = vmaxf(array[11], array[13]); + array[11] = tmp; + tmp = vminf(array[14], array[16]); + array[16] = vmaxf(array[14], array[16]); + array[14] = tmp; + tmp = vminf(array[15], array[17]); + array[17] = vmaxf(array[15], array[17]); + array[15] = tmp; + tmp = vminf(array[18], array[20]); + array[20] = vmaxf(array[18], array[20]); + array[18] = tmp; + tmp = vminf(array[19], array[21]); + array[21] = vmaxf(array[19], array[21]); + array[19] = tmp; + tmp = vminf(array[22], array[24]); + array[24] = vmaxf(array[22], array[24]); + array[22] = tmp; + tmp = vminf(array[23], array[25]); + array[25] = vmaxf(array[23], array[25]); + array[23] = tmp; + tmp = vminf(array[26], array[28]); + array[28] = vmaxf(array[26], array[28]); + array[26] = tmp; + tmp = vminf(array[27], array[29]); + array[29] = vmaxf(array[27], array[29]); + array[27] = tmp; + tmp = vminf(array[30], array[32]); + array[32] = vmaxf(array[30], array[32]); + array[30] = tmp; + tmp = vminf(array[31], array[33]); + array[33] = vmaxf(array[31], array[33]); + array[31] = tmp; + tmp = vminf(array[34], array[36]); + array[36] = vmaxf(array[34], array[36]); + array[34] = tmp; + tmp = vminf(array[35], array[37]); + array[37] = vmaxf(array[35], array[37]); + array[35] = tmp; + tmp = vminf(array[38], array[40]); + array[40] = vmaxf(array[38], array[40]); + array[38] = tmp; + tmp = vminf(array[39], array[41]); + array[41] = vmaxf(array[39], array[41]); + array[39] = tmp; + tmp = vminf(array[42], array[44]); + array[44] = vmaxf(array[42], array[44]); + array[42] = tmp; + tmp = vminf(array[43], array[45]); + array[45] = vmaxf(array[43], array[45]); + array[43] = tmp; + tmp = vminf(array[46], array[48]); + array[48] = vmaxf(array[46], array[48]); + array[46] = tmp; + tmp = vminf(array[47], array[49]); + array[49] = vmaxf(array[47], array[49]); + array[47] = tmp; + tmp = vminf(array[50], array[52]); + array[52] = vmaxf(array[50], array[52]); + array[50] = tmp; + tmp = vminf(array[51], array[53]); + array[53] = vmaxf(array[51], array[53]); + array[51] = tmp; + tmp = vminf(array[54], array[56]); + array[56] = vmaxf(array[54], array[56]); + array[54] = tmp; + tmp = vminf(array[55], array[57]); + array[57] = vmaxf(array[55], array[57]); + array[55] = tmp; + tmp = vminf(array[58], array[60]); + array[60] = vmaxf(array[58], array[60]); + array[58] = tmp; + tmp = vminf(array[59], array[61]); + array[61] = vmaxf(array[59], array[61]); + array[59] = tmp; + tmp = vminf(array[62], array[64]); + array[64] = vmaxf(array[62], array[64]); + array[62] = tmp; + tmp = vminf(array[63], array[65]); + array[65] = vmaxf(array[63], array[65]); + array[63] = tmp; + tmp = vminf(array[66], array[68]); + array[68] = vmaxf(array[66], array[68]); + array[66] = tmp; + tmp = vminf(array[67], array[69]); + array[69] = vmaxf(array[67], array[69]); + array[67] = tmp; + tmp = vminf(array[70], array[72]); + array[72] = vmaxf(array[70], array[72]); + array[70] = tmp; + tmp = vminf(array[71], array[73]); + array[73] = vmaxf(array[71], array[73]); + array[71] = tmp; + tmp = vminf(array[74], array[76]); + array[76] = vmaxf(array[74], array[76]); + array[74] = tmp; + tmp = vminf(array[75], array[77]); + array[77] = vmaxf(array[75], array[77]); + array[75] = tmp; + tmp = vminf(array[78], array[80]); + array[80] = vmaxf(array[78], array[80]); + array[78] = tmp; + array[1] = vmaxf(array[0], array[1]); + array[3] = vmaxf(array[2], array[3]); + array[5] = vmaxf(array[4], array[5]); + array[7] = vmaxf(array[6], array[7]); + array[9] = vmaxf(array[8], array[9]); + array[11] = vmaxf(array[10], array[11]); + array[13] = vmaxf(array[12], array[13]); + array[15] = vmaxf(array[14], array[15]); + array[17] = vmaxf(array[16], array[17]); + array[19] = vmaxf(array[18], array[19]); + array[21] = vmaxf(array[20], array[21]); + array[23] = vmaxf(array[22], array[23]); + array[25] = vmaxf(array[24], array[25]); + array[27] = vmaxf(array[26], array[27]); + array[29] = vmaxf(array[28], array[29]); + array[31] = vmaxf(array[30], array[31]); + array[33] = vmaxf(array[32], array[33]); + array[35] = vmaxf(array[34], array[35]); + array[37] = vmaxf(array[36], array[37]); + array[39] = vmaxf(array[38], array[39]); + array[40] = vminf(array[40], array[41]); + array[42] = vminf(array[42], array[43]); + array[44] = vminf(array[44], array[45]); + array[46] = vminf(array[46], array[47]); + array[48] = vminf(array[48], array[49]); + array[50] = vminf(array[50], array[51]); + array[52] = vminf(array[52], array[53]); + array[54] = vminf(array[54], array[55]); + array[56] = vminf(array[56], array[57]); + array[58] = vminf(array[58], array[59]); + array[60] = vminf(array[60], array[61]); + array[62] = vminf(array[62], array[63]); + array[64] = vminf(array[64], array[65]); + array[66] = vminf(array[66], array[67]); + array[68] = vminf(array[68], array[69]); + array[70] = vminf(array[70], array[71]); + array[72] = vminf(array[72], array[73]); + array[74] = vminf(array[74], array[75]); + array[76] = vminf(array[76], array[77]); + array[78] = vminf(array[78], array[79]); + array[64] = vmaxf(array[1], array[64]); + array[66] = vmaxf(array[3], array[66]); + array[68] = vmaxf(array[5], array[68]); + array[70] = vmaxf(array[7], array[70]); + array[9] = vminf(array[9], array[72]); + array[11] = vminf(array[11], array[74]); + array[13] = vminf(array[13], array[76]); + array[15] = vminf(array[15], array[78]); + array[17] = vminf(array[17], array[80]); + array[40] = vmaxf(array[9], array[40]); + array[42] = vmaxf(array[11], array[42]); + array[44] = vmaxf(array[13], array[44]); + array[46] = vmaxf(array[15], array[46]); + array[48] = vmaxf(array[17], array[48]); + array[50] = vmaxf(array[19], array[50]); + array[52] = vmaxf(array[21], array[52]); + array[54] = vmaxf(array[23], array[54]); + array[25] = vminf(array[25], array[56]); + array[27] = vminf(array[27], array[58]); + array[29] = vminf(array[29], array[60]); + array[31] = vminf(array[31], array[62]); + array[33] = vminf(array[33], array[64]); + array[35] = vminf(array[35], array[66]); + array[37] = vminf(array[37], array[68]); + array[39] = vminf(array[39], array[70]); + array[40] = vmaxf(array[25], array[40]); + array[42] = vmaxf(array[27], array[42]); + array[44] = vmaxf(array[29], array[44]); + array[46] = vmaxf(array[31], array[46]); + array[33] = vminf(array[33], array[48]); + array[35] = vminf(array[35], array[50]); + array[37] = vminf(array[37], array[52]); + array[39] = vminf(array[39], array[54]); + array[40] = vmaxf(array[33], array[40]); + array[42] = vmaxf(array[35], array[42]); + array[37] = vminf(array[37], array[44]); + array[39] = vminf(array[39], array[46]); + array[40] = vmaxf(array[37], array[40]); + array[39] = vminf(array[39], array[42]); + return vmaxf(array[39], array[40]); +} +#endif + +template +inline T median(T arg, ARGS... args) +{ + return median(std::array{std::move(arg), std::move(args)...}); +} + +template +inline std::array middle4of6(const std::array& array) +{ + std::array res; + + res[0] = std::min(array[1], array[2]); + res[1] = std::max(array[1], array[2]); + T left = std::min(array[0], res[1]); + res[1] = std::max(array[0], res[1]); + T tmp = std::min(left, res[0]); + res[0] = std::max(left, res[0]); + left = tmp; + res[3] = std::min(array[4], array[5]); + T right = std::max(array[4], array[5]); + res[2] = std::min(array[3], right); + right = std::max(array[3], right); + tmp = std::min(res[2], res[3]); + res[3] = std::max(res[2], res[3]); + res[2] = std::max(left, tmp); + res[1] = std::min(res[1], right); + + return res; +} + +template<> +inline std::array middle4of6(const std::array& array) +{ + std::array res; + + res[0] = vminf(array[1], array[2]); + res[1] = vmaxf(array[1], array[2]); + vfloat left = vminf(array[0], res[1]); + res[1] = vmaxf(array[0], res[1]); + vfloat tmp = vminf(left, res[0]); + res[0] = vmaxf(left, res[0]); + left = tmp; + res[3] = vminf(array[4], array[5]); + vfloat right = vmaxf(array[4], array[5]); + res[2] = vminf(array[3], right); + right = vmaxf(array[3], right); + tmp = vminf(res[2], res[3]); + res[3] = vmaxf(res[2], res[3]); + res[2] = vmaxf(left, tmp); + res[1] = vminf(res[1], right); + + return res; +} + +template +inline std::array middle4of6(T arg0, T arg1, T arg2, T arg3, T arg4, T arg5) +{ + return middle4of6(std::array{std::move(arg0), std::move(arg1), std::move(arg2), std::move(arg3), std::move(arg4), std::move(arg5)}); } diff --git a/rtengine/minmax.h b/rtengine/minmax.h deleted file mode 100644 index 69e939b72..000000000 --- a/rtengine/minmax.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * This file is part of RawTherapee. - * - * Copyright (c) 2004-2010 Gabor Horvath - * - * 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 . - */ -#define MINMAX3(a,b,c,min,max) \ -{ \ -if ((a)<(b)) { \ - if ((b)<(c)) { \ - (min) = (a); \ - (max) = (c); \ - } \ - else { \ - (max) = (b); \ - if ((a)<(c)) \ - (min) = (a); \ - else \ - (min) = (c); \ - } \ -} else { \ - if ((b)>(c)) { \ - (min) = (c); \ - (max) = (a); \ - } \ - else { \ - (min) = (b); \ - if ((a)>(c)) \ - (max) = (a); \ - else \ - (max) = (c); \ - } \ -} \ -} - -#define MIN3(a,b,c,min) \ -{ \ -if ((a)<(b)) { \ - if ((a)<(c)) \ - (min) = (a); \ - else \ - (min) = (c); \ -} else { \ - if ((b)>(c)) \ - (min) = (c); \ - else \ - (min) = (b); \ -} \ -} - -#define MAX3(a,b,c,min) \ -{ \ -if ((a)>(b)) { \ - if ((a)>(c)) \ - (max) = (a); \ - else \ - (max) = (c); \ -} else { \ - if ((b)<(c)) \ - (max) = (c); \ - else \ - (max) = (b); \ -} \ -} diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 60a54baf5..70b764da1 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -1038,8 +1038,8 @@ void ProcParams::setDefaults () prsharpening.edges_tolerance = 1800; prsharpening.halocontrol = false; prsharpening.halocontrol_amount = 85; - prsharpening.method = "usm"; - prsharpening.deconvradius = 0.5; + prsharpening.method = "rld"; + prsharpening.deconvradius = 0.45; prsharpening.deconviter = 100; prsharpening.deconvdamping = 0; prsharpening.deconvamount = 100; @@ -1149,10 +1149,10 @@ void ProcParams::setDefaults () crop.y = -1; crop.w = 15000; crop.h = 15000; - crop.fixratio = false; + crop.fixratio = true; crop.ratio = "3:2"; crop.orientation = "As Image"; - crop.guide = "Rule of thirds"; + crop.guide = "Frame"; coarse.setDefaults(); diff --git a/rtengine/rawimagesource.cc b/rtengine/rawimagesource.cc index 56ef57a07..a7ca7d86c 100644 --- a/rtengine/rawimagesource.cc +++ b/rtengine/rawimagesource.cc @@ -421,25 +421,6 @@ extern const Settings* settings; #define ABS(a) ((a)<0?-(a):(a)) #define DIST(a,b) (ABS(a-b)) -#define PIX_SORT(a,b) { if ((a)>(b)) {temp=(a);(a)=(b);(b)=temp;} } - -#define med3x3(a0,a1,a2,a3,a4,a5,a6,a7,a8,median) { \ -p[0]=a0; p[1]=a1; p[2]=a2; p[3]=a3; p[4]=a4; p[5]=a5; p[6]=a6; p[7]=a7; p[8]=a8; \ -PIX_SORT(p[1],p[2]); PIX_SORT(p[4],p[5]); PIX_SORT(p[7],p[8]); \ -PIX_SORT(p[0],p[1]); PIX_SORT(p[3],p[4]); PIX_SORT(p[6],p[7]); \ -PIX_SORT(p[1],p[2]); PIX_SORT(p[4],p[5]); PIX_SORT(p[7],p[8]); \ -PIX_SORT(p[0],p[3]); PIX_SORT(p[5],p[8]); PIX_SORT(p[4],p[7]); \ -PIX_SORT(p[3],p[6]); PIX_SORT(p[1],p[4]); PIX_SORT(p[2],p[5]); \ -PIX_SORT(p[4],p[7]); PIX_SORT(p[4],p[2]); PIX_SORT(p[6],p[4]); \ -PIX_SORT(p[4],p[2]); median=p[4];} //a4 is the median - -#define med5(a0,a1,a2,a3,a4,median) { \ -p[0]=a0; p[1]=a1; p[2]=a2; p[3]=a3; p[4]=a4; \ -PIX_SORT(p[0],p[1]) ; PIX_SORT(p[3],p[4]) ; PIX_SORT(p[0],p[3]) ; \ -PIX_SORT(p[1],p[4]) ; PIX_SORT(p[1],p[2]) ; PIX_SORT(p[2],p[3]) ; \ -PIX_SORT(p[1],p[2]) ; median=p[2] ;} - - RawImageSource::RawImageSource () : ImageSource() , plistener(NULL) @@ -1339,12 +1320,10 @@ SSEFUNCTION int RawImageSource::findHotDeadPixels( PixelsMap &bpMap, float thres #endif for (int i = 2; i < H - 2; i++) { - float p[9], temp; // we need this for med3x3 macro - for (int j = 2; j < W - 2; j++) { - med3x3(rawData[i - 2][j - 2], rawData[i - 2][j], rawData[i - 2][j + 2], - rawData[i][j - 2], rawData[i][j], rawData[i][j + 2], - rawData[i + 2][j - 2], rawData[i + 2][j], rawData[i + 2][j + 2], temp); + const float& temp = median(rawData[i - 2][j - 2], rawData[i - 2][j], rawData[i - 2][j + 2], + rawData[i][j - 2], rawData[i][j], rawData[i][j + 2], + rawData[i + 2][j - 2], rawData[i + 2][j], rawData[i + 2][j + 2]); cfablur[i * W + j] = rawData[i][j] - temp; } } @@ -3534,17 +3513,12 @@ void RawImageSource::processFalseColorCorrectionThread (Imagefloat* im, array2D vfloat* pre2 = &buffer[3]; vfloat* post1 = &buffer[6]; vfloat* post2 = &buffer[9]; - - vfloat middle[6]; - #else float buffer[12]; float* pre1 = &buffer[0]; float* pre2 = &buffer[3]; float* post1 = &buffer[6]; float* post2 = &buffer[9]; - - float middle[6]; #endif int px = (row_from - 1) % 3, cx = row_from % 3, nx = 0; @@ -3568,7 +3542,6 @@ void RawImageSource::processFalseColorCorrectionThread (Imagefloat* im, array2D #ifdef __SSE2__ pre1[0] = _mm_setr_ps(rbconv_I[px][0], rbconv_Q[px][0], 0, 0) , pre1[1] = _mm_setr_ps(rbconv_I[cx][0], rbconv_Q[cx][0], 0, 0), pre1[2] = _mm_setr_ps(rbconv_I[nx][0], rbconv_Q[nx][0], 0, 0); pre2[0] = _mm_setr_ps(rbconv_I[px][1], rbconv_Q[px][1], 0, 0) , pre2[1] = _mm_setr_ps(rbconv_I[cx][1], rbconv_Q[cx][1], 0, 0), pre2[2] = _mm_setr_ps(rbconv_I[nx][1], rbconv_Q[nx][1], 0, 0); - vfloat temp[7]; // fill first element in rbout_I and rbout_Q rbout_I[cx][0] = rbconv_I[cx][0]; @@ -3577,13 +3550,12 @@ void RawImageSource::processFalseColorCorrectionThread (Imagefloat* im, array2D // median I channel for (int j = 1; j < W - 2; j += 2) { post1[0] = _mm_setr_ps(rbconv_I[px][j + 1], rbconv_Q[px][j + 1], 0, 0), post1[1] = _mm_setr_ps(rbconv_I[cx][j + 1], rbconv_Q[cx][j + 1], 0, 0), post1[2] = _mm_setr_ps(rbconv_I[nx][j + 1], rbconv_Q[nx][j + 1], 0, 0); - VMIDDLE4OF6(pre2[0], pre2[1], pre2[2], post1[0], post1[1], post1[2], middle[0], middle[1], middle[2], middle[3], middle[4], middle[5], temp[0]); - vfloat medianval; - VMEDIAN7(pre1[0], pre1[1], pre1[2], middle[1], middle[2], middle[3], middle[4], temp[0], temp[1], temp[2], temp[3], temp[4], temp[5], temp[6], medianval); + const auto middle = middle4of6(pre2[0], pre2[1], pre2[2], post1[0], post1[1], post1[2]); + vfloat medianval = median(pre1[0], pre1[1], pre1[2], middle[0], middle[1], middle[2], middle[3]); rbout_I[cx][j] = medianval[0]; rbout_Q[cx][j] = medianval[1]; post2[0] = _mm_setr_ps(rbconv_I[px][j + 2], rbconv_Q[px][j + 2], 0, 0), post2[1] = _mm_setr_ps(rbconv_I[cx][j + 2], rbconv_Q[cx][j + 2], 0, 0), post2[2] = _mm_setr_ps(rbconv_I[nx][j + 2], rbconv_Q[nx][j + 2], 0, 0); - VMEDIAN7(post2[0], post2[1], post2[2], middle[1], middle[2], middle[3], middle[4], temp[0], temp[1], temp[2], temp[3], temp[4], temp[5], temp[6], medianval); + medianval = median(post2[0], post2[1], post2[2], middle[0], middle[1], middle[2], middle[3]); rbout_I[cx][j + 1] = medianval[0]; rbout_Q[cx][j + 1] = medianval[1]; std::swap(pre1, post1); @@ -3599,7 +3571,6 @@ void RawImageSource::processFalseColorCorrectionThread (Imagefloat* im, array2D #else pre1[0] = rbconv_I[px][0], pre1[1] = rbconv_I[cx][0], pre1[2] = rbconv_I[nx][0]; pre2[0] = rbconv_I[px][1], pre2[1] = rbconv_I[cx][1], pre2[2] = rbconv_I[nx][1]; - float temp[7]; // fill first element in rbout_I rbout_I[cx][0] = rbconv_I[cx][0]; @@ -3607,10 +3578,10 @@ void RawImageSource::processFalseColorCorrectionThread (Imagefloat* im, array2D // median I channel for (int j = 1; j < W - 2; j += 2) { post1[0] = rbconv_I[px][j + 1], post1[1] = rbconv_I[cx][j + 1], post1[2] = rbconv_I[nx][j + 1]; - MIDDLE4OF6(pre2[0], pre2[1], pre2[2], post1[0], post1[1], post1[2], middle[0], middle[1], middle[2], middle[3], middle[4], middle[5], temp[0]); - MEDIAN7(pre1[0], pre1[1], pre1[2], middle[1], middle[2], middle[3], middle[4], temp[0], temp[1], temp[2], temp[3], temp[4], temp[5], temp[6], rbout_I[cx][j]); + const auto middle = middle4of6(pre2[0], pre2[1], pre2[2], post1[0], post1[1], post1[2]); + rbout_I[cx][j] = median(pre1[0], pre1[1], pre1[2], middle[0], middle[1], middle[2], middle[3]); post2[0] = rbconv_I[px][j + 2], post2[1] = rbconv_I[cx][j + 2], post2[2] = rbconv_I[nx][j + 2]; - MEDIAN7(post2[0], post2[1], post2[2], middle[1], middle[2], middle[3], middle[4], temp[0], temp[1], temp[2], temp[3], temp[4], temp[5], temp[6], rbout_I[cx][j + 1]); + rbout_I[cx][j + 1] = median(post2[0], post2[1], post2[2], middle[0], middle[1], middle[2], middle[3]); std::swap(pre1, post1); std::swap(pre2, post2); } @@ -3628,10 +3599,10 @@ void RawImageSource::processFalseColorCorrectionThread (Imagefloat* im, array2D // median Q channel for (int j = 1; j < W - 2; j += 2) { post1[0] = rbconv_Q[px][j + 1], post1[1] = rbconv_Q[cx][j + 1], post1[2] = rbconv_Q[nx][j + 1]; - MIDDLE4OF6(pre2[0], pre2[1], pre2[2], post1[0], post1[1], post1[2], middle[0], middle[1], middle[2], middle[3], middle[4], middle[5], temp[0]); - MEDIAN7(pre1[0], pre1[1], pre1[2], middle[1], middle[2], middle[3], middle[4], temp[0], temp[1], temp[2], temp[3], temp[4], temp[5], temp[6], rbout_Q[cx][j]); + const auto middle = middle4of6(pre2[0], pre2[1], pre2[2], post1[0], post1[1], post1[2]); + rbout_Q[cx][j] = median(pre1[0], pre1[1], pre1[2], middle[0], middle[1], middle[2], middle[3]); post2[0] = rbconv_Q[px][j + 2], post2[1] = rbconv_Q[cx][j + 2], post2[2] = rbconv_Q[nx][j + 2]; - MEDIAN7(post2[0], post2[1], post2[2], middle[1], middle[2], middle[3], middle[4], temp[0], temp[1], temp[2], temp[3], temp[4], temp[5], temp[6], rbout_Q[cx][j + 1]); + rbout_Q[cx][j + 1] = median(post2[0], post2[1], post2[2], middle[0], middle[1], middle[2], middle[3]); std::swap(pre1, post1); std::swap(pre2, post2); } @@ -3804,11 +3775,10 @@ void RawImageSource::colorSpaceConversion_ (Imagefloat* im, ColorManagementParam pre_mul[2] }; const DCPProfile::Matrix cam_matrix = {{ - {camMatrix[0][0], camMatrix[0][1], camMatrix[0][2]}, - {camMatrix[1][0], camMatrix[1][1], camMatrix[1][2]}, - {camMatrix[2][0], camMatrix[2][1], camMatrix[2][2]} - } - }; + {camMatrix[0][0], camMatrix[0][1], camMatrix[0][2]}, + {camMatrix[1][0], camMatrix[1][1], camMatrix[1][2]}, + {camMatrix[2][0], camMatrix[2][1], camMatrix[2][2]} + }}; dcpProf->apply(im, cmp.dcpIlluminant, cmp.working, wb, pre_mul_row, cam_matrix, cmp.applyHueSatMap); return; } @@ -5255,11 +5225,4 @@ void RawImageSource::cleanup () delete phaseOneIccCurveInv; } -#undef PIX_SORT -#undef med3x3 - } /* namespace */ - -#undef PIX_SORT -#undef med3x3 - diff --git a/rtengine/rt_math.h b/rtengine/rt_math.h index 898f1397c..0836c8be7 100644 --- a/rtengine/rt_math.h +++ b/rtengine/rt_math.h @@ -11,10 +11,10 @@ static const float MAXVALF = float(MAXVAL); // float version of MAXVAL static const double MAXVALD = double(MAXVAL); // double version of MAXVAL template -inline const _Tp SQR (_Tp x) +inline _Tp SQR (_Tp x) { // return std::pow(x,2); Slower than: - return (x * x); + return x * x; } template @@ -31,25 +31,19 @@ inline const _Tp& max(const _Tp& a, const _Tp& b) template -inline const _Tp LIM(const _Tp& a, const _Tp& b, const _Tp& c) +inline const _Tp& LIM(const _Tp& a, const _Tp& b, const _Tp& c) { return std::max(b, std::min(a, c)); } template -inline const _Tp LIM01(const _Tp& a) +inline _Tp LIM01(const _Tp& a) { return std::max(_Tp(0), std::min(a, _Tp(1))); } template -inline const _Tp ULIM(const _Tp& a, const _Tp& b, const _Tp& c) -{ - return ((b < c) ? LIM(a, b, c) : LIM(a, c, b)); -} - -template -inline const _Tp CLIP(const _Tp& a) +inline _Tp CLIP(const _Tp& a) { return LIM(a, static_cast<_Tp>(0), static_cast<_Tp>(MAXVAL)); } @@ -80,7 +74,7 @@ inline const _Tp& max(const _Tp& a, const _Tp& b, const _Tp& c, const _Tp& d) } template -inline const _Tp intp(const _Tp a, const _Tp b, const _Tp c) +inline _Tp intp(_Tp a, _Tp b, _Tp c) { // calculate a * b + (1 - a) * c // following is valid: @@ -90,19 +84,19 @@ inline const _Tp intp(const _Tp a, const _Tp b, const _Tp c) } template -T norm1(const T& x, const T& y) +inline T norm1(const T& x, const T& y) { return std::abs(x) + std::abs(y); } template -T norm2(const T& x, const T& y) +inline T norm2(const T& x, const T& y) { return std::sqrt(x * x + y * y); } template< typename T > -T norminf(const T& x, const T& y) +inline T norminf(const T& x, const T& y) { return std::max(std::abs(x), std::abs(y)); } diff --git a/rtengine/sleefsseavx.c b/rtengine/sleefsseavx.c index 1d15e1e41..a9f49f143 100644 --- a/rtengine/sleefsseavx.c +++ b/rtengine/sleefsseavx.c @@ -1334,12 +1334,6 @@ static INLINE vfloat LIMV( vfloat a, vfloat b, vfloat c ) { return vmaxf( b, vminf(a,c)); } -static INLINE vfloat ULIMV( vfloat a, vfloat b, vfloat c ){ - // made to clamp a in range [b,c] but in fact it's also the median of a,b,c, which means that the result is independent on order of arguments - // ULIMV(a,b,c) = ULIMV(a,c,b) = ULIMV(b,a,c) = ULIMV(b,c,a) = ULIMV(c,a,b) = ULIMV(c,b,a) - return vmaxf(vminf(a,b), vminf(vmaxf(a,b),c)); -} - static INLINE vfloat SQRV(vfloat a){ return a * a; } diff --git a/rtgui/prsharpening.cc b/rtgui/prsharpening.cc index 8746f7e96..5e79d078a 100644 --- a/rtgui/prsharpening.cc +++ b/rtgui/prsharpening.cc @@ -18,7 +18,6 @@ */ #include "prsharpening.h" #include -#include "guiutils.h" using namespace rtengine; using namespace rtengine::procparams; @@ -45,10 +44,10 @@ PrSharpening::PrSharpening () : FoldableToolPanel(this, "prsharpening", M("TP_PR pack_start (*hb); rld = new Gtk::VBox (); - dradius = Gtk::manage (new Adjuster (M("TP_SHARPENING_EDRADIUS"), 0.5, 2.5, 0.01, 0.75)); - damount = Gtk::manage (new Adjuster (M("TP_SHARPENING_RLD_AMOUNT"), 0.0, 100, 1, 75)); - ddamping = Gtk::manage (new Adjuster (M("TP_SHARPENING_RLD_DAMPING"), 0, 100, 1, 20)); - diter = Gtk::manage (new Adjuster (M("TP_SHARPENING_RLD_ITERATIONS"), 5, 100, 1, 30)); + dradius = Gtk::manage (new Adjuster (M("TP_SHARPENING_EDRADIUS"), 0.4, 2.5, 0.01, 0.45)); + damount = Gtk::manage (new Adjuster (M("TP_SHARPENING_RLD_AMOUNT"), 0.0, 100, 1, 100)); + ddamping = Gtk::manage (new Adjuster (M("TP_SHARPENING_RLD_DAMPING"), 0, 100, 1, 0)); + diter = Gtk::manage (new Adjuster (M("TP_SHARPENING_RLD_ITERATIONS"), 5, 100, 1, 100)); rld->pack_start (*dradius); rld->pack_start (*damount); rld->pack_start (*ddamping); @@ -85,7 +84,7 @@ PrSharpening::PrSharpening () : FoldableToolPanel(this, "prsharpening", M("TP_PR edgesonly->set_active (false); edgebox = new Gtk::VBox (); eradius = Gtk::manage (new Adjuster (M("TP_SHARPENING_EDRADIUS"), 0.5, 2.5, 0.1, 1.9)); - etolerance = Gtk::manage (new Adjuster (M("TP_SHARPENING_EDTOLERANCE"), 10, 10000, 100, 1000)); + etolerance = Gtk::manage (new Adjuster (M("TP_SHARPENING_EDTOLERANCE"), 10, 10000, 100, 1800)); usm->pack_start(*hsep6, Gtk::PACK_SHRINK, 2); usm->pack_start(*edgesonly); edgebox->pack_start(*eradius); diff --git a/rtgui/sharpening.cc b/rtgui/sharpening.cc index c803d46ef..6c5cd2e4b 100644 --- a/rtgui/sharpening.cc +++ b/rtgui/sharpening.cc @@ -80,7 +80,7 @@ Sharpening::Sharpening () : FoldableToolPanel(this, "sharpening", M("TP_SHARPENI edgesonly->set_active (false); edgebox = new Gtk::VBox (); eradius = Gtk::manage (new Adjuster (M("TP_SHARPENING_EDRADIUS"), 0.5, 2.5, 0.1, 1.9)); - etolerance = Gtk::manage (new Adjuster (M("TP_SHARPENING_EDTOLERANCE"), 10, 10000, 100, 1000)); + etolerance = Gtk::manage (new Adjuster (M("TP_SHARPENING_EDTOLERANCE"), 10, 10000, 100, 1800)); usm->pack_start(*hsep6, Gtk::PACK_SHRINK, 2); usm->pack_start(*edgesonly); edgebox->pack_start(*eradius);