//=============================================================================== // Copyright (c) 2007-2016 Advanced Micro Devices, Inc. All rights reserved. // Copyright (c) 2004-2006 ATI Technologies Inc. //=============================================================================== // // 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. // #include #include #include #include "3dquant_constants.h" #include "3dquant_vpc.h" #include "reconstruct.h" #include "debug.h" static double maxStep[MAX_CLUSTERS] = {0,0,0,0,0,0,0,0}; static double maxStep1[MAX_CLUSTERS]= {0,0,0,0,0,0,0,0}; static double minStep[MAX_CLUSTERS] = {1000,1000,1000,1000,1000,1000,1000,1000}; static double minStep1[MAX_CLUSTERS]= {1000,1000,1000,1000,1000,1000,1000,1000}; static int stepHisto[512*16]; static int stepHisto1[512*16]; static int stepHistoI[MAX_SUBSETS][512*16]; static int histoInit =0; static double NShakeCnt=0; static double PCnt=0; void histoStep (double step, double step1) { #ifdef USE_DBGTRACE DbgTrace(()); #endif if (histoInit==0) { int i; for (i=0; i<512*16; i++) stepHisto[i]=stepHisto1[i]=0; histoInit=1; } step *= 16; step = step <0 ? 0 : step; step = step >512.*16 ? 512.*16 : step; stepHisto[(int)floor(step+1/2.)]++; step1 *= 16; step1 = step1 <0 ? 0 : step1; step1 = step1 >512.*16 ? 512.*16 : step1; stepHisto1[(int)floor(step1+1/2.)]++; }; void histoStepCnt (int id, int cnt, double step1) { if (histoInit==0) { int i; for (i=0; i<512*16; i++) stepHisto[i]=stepHisto1[i]=0; histoInit=1; } step1 *= 16; step1 = step1 <0 ? 0 : step1; step1 = step1 >512.*16 ? 512.*16 : step1; stepHistoI[id][(int)floor(step1+1/2.)]+=cnt; }; void printStepHistoI (void) { #ifdef USE_DBGTRACE DbgTrace(()); #endif int i,j,k,l; for (l=0; ln-x, but this does not matter below (int index[], int numEntries) { #ifdef USE_DBGTRACE DbgTrace(()); #endif int k; int d,D; int mi; int Mi; if (numEntries ==0) return; mi=Mi=index[0]; for (k=0; k index[k] ? Mi : index[k]; } D=1; for (d=2; d<=Mi; d++) { for (k=0; k=numEntries) D =d; } for (k=0; kn-x, but this does not matter below (int index[], int numEntries, int max_clusters) { #ifdef USE_DBGTRACE DbgTrace(()); #endif int k; int d; int Mi=0,mi=max_clusters-1; for (k=0; k index[k] ? Mi : index[k]; } d = Mi-mi == 0 ? 1 : (max_clusters-1)/(Mi-mi); for (k=0; k index[k] ? Mi : index[k]; if (step!=0.) minStep[Mi] = minStep[Mi] < step ? minStep[Mi] : step; maxStep[Mi] = maxStep[Mi] > step ? maxStep[Mi] : step; if (step1!=0.) minStep1[Mi] = minStep1[Mi] < step1 ? minStep1[Mi] : step1; if (step1!=0.) maxStep1[Mi] = maxStep1[Mi] > step1 ? maxStep1[Mi] : step1; } double reconstruct( double data[MAX_ENTRIES][DIMENSION], int numEntries, int index_[MAX_ENTRIES], double out[MAX_ENTRIES][DIMENSION],int ns, double direction [DIMENSION],double *step ) { #ifdef USE_DBGTRACE DbgTrace(()); #endif double s=0,t=0, q=0; int i,j,k; double mean[DIMENSION]; int index[MAX_ENTRIES]; for (k=0; k q1 ? fabs(direction[j]) : q1; } s /= (double) numEntries; t = t - s * s * (double) numEntries; t = (t == 0 ? 0. : 1/t); q=sqrt(q); *step=t*q; for (j=0; j=1.0001) printf("error\n"); } if (*step !=0) *step*=q1/q; for (i=0; i q1 ? fabs(direction[j]) : q1; } s /= (double) numEntries; t = t - s * s * (double) numEntries; t = (t == 0 ? 0. : 1/t); q=sqrt(q); *step=t*q; for (j=0; j=1.0001) printf("error\n"); } double step_l2=*step; if (*step !=0) *step*=q1/q; double step_li=*step; sHisto ( index, numEntries, step_l2, step_li); histoStep (step_l2, step_li); for (i=0; i0 ? c[i][j]:0; c[i][j]= c[i][j]<255. ? c[i][j]:255.; t2[i]+=c[i][j]*c[i][j]/2; // negative } } ea=0; for (i=0; i < numEntries; i++) { double e = t2[0]-data[i][0]*c[0][0]-data[i][1]*c[0][1]-data[i][2]*c[0][2]; index_t[i]=0; for (k=1; k0 ? c[i][j]:0; c[i][j]= c[i][j]<255. ? c[i][j]:255.; t2[i]+=c[i][j]*c[i][j]/2; // negative } } ea=0; for (i=0; i < numEntries; i++) { double e = t2[0]-data[i][0]*c[0][0]-data[i][1]*c[0][1]-data[i][2]*c[0][2]; index_t[i]=0; for (k=1; k q1 ? fabs(direction[j]) : q1; } *idx_mean= (s /= (double) numEntries); t = t - s * s * (double) numEntries; t = (t == 0 ? 0. : 1/t); *step=t*q1; for (j=0; j=1.0001) printf("error\n"); } } void mds_d ( double data[MAX_ENTRIES][DIMENSION],int numEntries, int index[MAX_ENTRIES], double mean[DIMENSION], double *idx_mean, double direction [DIMENSION],double *step) { #ifdef USE_DBGTRACE DbgTrace(()); #endif int i,j,k; double t=0,s=0,q1=0; double cc[MAX_CLUSTERS_BIG][DIMENSION]; int cnt[MAX_CLUSTERS_BIG]; for (i=0; i q1 ? fabs(direction[j]) : q1; } *idx_mean= (s /= (double) numEntries); t = t - s * s * (double) numEntries; t = (t == 0 ? 0. : 1/t); *step=t*q1; for (j=0; j=1.0001) printf("error\n"); } } //mean rounding setup // cube model void setMean( double mean[DIMENSION], double mr[8][DIMENSION], int div ) { #ifdef USE_DBGTRACE DbgTrace(()); #endif double idiv=1.; // full scale divider per component int sdiv=1 ; // Z/fcc/bcc swithc int j,k; while (div >=8) { div /=8; idiv *=2.; } sdiv = div; // bcc*2 and cartesian; starting points for fcc mr[4][0]=(mr[0][0]=floor(mean[0]/idiv))+1.; if (sdiv==4) { // switch to search in bcc*2 for (k=0; k<5; k+=4) { if ( (int) floor(mr[k][0]+0.5) & 1 ) { mr[k][1]=floor((mean[1]/idiv-1.)/2.)+1./2.; mr[k][2]=floor((mean[2]/idiv-1.)/2.)+1./2.; } else { mr[k][1]=floor(mean[1]/idiv/2.); mr[k][2]=floor(mean[2]/idiv/2.); } } } else { mr[4][1]=mr[0][1]=floor(mean[1]/idiv); mr[4][2]=mr[0][2]=floor(mean[2]/idiv); } // search in fcc for (k=0; k<5; k+=4) { if (sdiv==2) { if ((int) floor(mr[k][0]+mr[k][1]+mr[k][2] +0.5) & 1) { //latice point, leave [0] be, if (-mr[k][1]+mr[k][2] < -(mean[1]/idiv)+(mean[2]/idiv)) { // [-1,1] mr[k][1]--; mr[k][2]++; } // else Ok to go } else { if (mr[k][1]+ 1 + mr[k][2] < (mean[1]/idiv)+(mean[2]/idiv)) // get to [0,1] and go right mr[k][2]++; else // get to [-1,0] and go right mr[k][1]--; } } } if (sdiv==2) { mr[1][0] =mr[0][0]; mr[1][1] =mr[0][1]+1.; mr[1][2] =mr[0][2]+1.; mr[2][0] =mr[0][0]; mr[2][1] =mr[0][1]+1.; mr[2][2] =mr[0][2]-1.; mr[3][0] =mr[0][0]; mr[3][1] =mr[0][1]+1.; mr[3][2] =mr[0][2]; mr[5][0] =mr[4][0]; mr[5][1] =mr[4][1]+1.; mr[5][2] =mr[4][2]+1.; mr[6][0] =mr[4][0]; mr[6][1] =mr[4][1]+1.; mr[6][2] =mr[4][2]-1.; mr[7][0] =mr[4][0]; mr[7][1] =mr[4][1]+1.; mr[7][2] =mr[4][2]; } else { mr[1][0] =mr[0][0]; mr[1][1] =mr[0][1]+1.; mr[1][2] =mr[0][2]; mr[2][0] =mr[0][0]; mr[2][1] =mr[0][1]; mr[2][2] =mr[0][2]+1.; mr[3][0] =mr[0][0]; mr[3][1] =mr[0][1]+1.; mr[3][2] =mr[0][2]+1.; mr[5][0] =mr[4][0]; mr[5][1] =mr[4][1]+1.; mr[5][2] =mr[4][2]; mr[6][0] =mr[4][0]; mr[6][1] =mr[4][1]; mr[6][2] =mr[4][2]+1.; mr[7][0] =mr[4][0]; mr[7][1] =mr[4][1]+1.; mr[7][2] =mr[4][2]+1.; } if (sdiv==4) // search in bcc*2 for (k=0; k<8; k++) for (j=1; j 255. ? 255. :mr[k][j]); } } double reconstruct_rnd( double data[MAX_ENTRIES][DIMENSION], int numEntries, int index_[MAX_ENTRIES], double out[MAX_ENTRIES][DIMENSION],int ns, double direction [DIMENSION],double *step ) { #ifdef USE_DBGTRACE DbgTrace(()); #endif #define NP1 31 static int code1[NP1][3]= // step, mean div,diamond /* GOOD */ { {7, 1, 2}, {11, 1, 2}, {15, 1, 2}, {19, 1, 4}, {24, 1, 4}, {29, 1, 4}, {34, 1, 4}, {40, 1, 4}, {46, 1, 4}, {53, 1, 4}, {60, 2, 1}, {67, 2, 1}, {75, 2, 1}, {83, 2, 1}, {92, 2, 2}, {101, 2, 2}, {111, 2, 2}, {122, 2, 2}, {133, 2, 2}, {145, 2, 2}, {158, 2, 2}, {172, 2, 2},{187, 2, 2}, {204, 2, 4}, {223, 2, 4}, {245, 2, 4}, {270, 2, 4}, {301, 4, 1}, {339, 4, 1}, {392, 4, 1}, {448, 4, 1} }; #define NP2 7 static int code2[NP2][3]= // step, mean div,diamond {{7,4,2}, {13, 8, 1},{26, 8, 1},{48, 8, 1},{79, 8, 2},{111, 16, 1},{158, 16, 1}}; int dir_limit1=13; int dir_limit2=6; static int report[3]= {0,0,0}; int (*code)[3]; int dir_limit=dir_limit1; int np; //############################## if (ns==3) { //############################## code = code2; dir_limit=dir_limit2; np=NP2; } else { code = code1; dir_limit=dir_limit1; np=NP1; } if (! report[ns]) { report[ns]=1; int bd=1; int s,i; printf("Quantizer report, sets %d\n",ns); for (i=0; i1) { b--; bd/=2; } printf("Tight estimate, TOTAL %g\n",b); } int i,j,k; static double mean[DIMENSION]; int ok; int maxTry=10; static int index[MAX_ENTRIES]; static int index_r[MAX_ENTRIES]; for (i=0; i 200000 ) {// bypass { NShakeCnt+=numEntries; for (i=0; i255 ? 255:mean_r[0][j]+MEAN_DIV*ii[j]; step_li = floor((step_li*STEP_FACTOR+.5)); step_li = step_li >256*STEP_FACTOR ? 256*STEP_FACTOR : step_li; int mc =-1; double tt = 2; for (i=0; i 0 ); return totalError(data,out,numEntries); }; double reconstruct_rnd_mean_clip( double data[MAX_ENTRIES][DIMENSION], int numEntries, int index_[MAX_ENTRIES], double out[MAX_ENTRIES][DIMENSION],int ns, double direction [DIMENSION], double *step, double in_mean[DIMENSION] ) { #ifdef USE_DBGTRACE DbgTrace(()); #endif #define NP1 31 static int code1[NP1][3]= // step, mean div,diamond /* GOOD */ { {7, 1, 2}, {11, 1, 2}, {15, 1, 2}, {19, 1, 4}, {24, 1, 4}, {29, 1, 4}, {34, 1, 4}, {40, 1, 4}, {46, 1, 4}, {53, 1, 4}, {60, 2, 1}, {67, 2, 1}, {75, 2, 1}, {83, 2, 1}, {92, 2, 2}, {101, 2, 2}, {111, 2, 2}, {122, 2, 2}, {133, 2, 2}, {145, 2, 2}, {158, 2, 2}, {172, 2, 2},{187, 2, 2}, {204, 2, 4}, {223, 2, 4}, {245, 2, 4}, {270, 2, 4}, {301, 4, 1}, {339, 4, 1}, {392, 4, 1}, {448, 4, 1} }; #undef NP2 #define NP2 8 static int code2[NP2][3]= // step, mean div,diamond {{7,8,1}, {24, 8, 1},{46, 8, 1}, {75, 8, 1}, {111, 8, 1},{158, 8, 1}, {223, 8, 1}, {448, 8, 1}}; int dir_limit1=13; int dir_limit2=6; static int report[3]= {0,0,0}; int (*code)[3]; int dir_limit=dir_limit1; int np; if (ns==3) { code = code2; dir_limit=dir_limit2; np=NP2; } else { code = code1; dir_limit=dir_limit1; np=NP1; } if (! report[ns]) { report[ns]=1; int bd=1; int s,i; printf("Quantizer report, sets %d\n",ns); for (i=0; i1) { b--; bd/=2; } printf("Tight estimate, TOTAL %g\n",b); } int i,j,k; static double mean[DIMENSION]; int ok; int maxTry=10; static int index[MAX_ENTRIES]; static int index_r[MAX_ENTRIES]; for (i=0; i q1 ? fabs(direction[j]) : q1; } s /= (double) numEntries; t = t - s * s * (double) numEntries; t = (t == 0 ? 0. : 1/t); q=sqrt(q); *step=t*q; for (j=0; j=1.0001) printf("error\n"); } if (*step !=0) *step*=q1/q; double step_li=*step; static double dir_r[4][DIMENSION]; static double dir_step_r[2][4][DIMENSION]; // alternative for dir_r static double mean_r[8][DIMENSION]; static double mean_step_r[2][8][DIMENSION]; static double step_r[2]; if (step_li > 200000 ) {// bypass { NShakeCnt+=numEntries; for (i=0; i255 ? 255:mean_r[0][j]+MEAN_DIV*ii[j]; step_li = floor((step_li*STEP_FACTOR - STEP_FACTOR)/STEP_DIV)*STEP_DIV+STEP_FACTOR; step_li = step_li < STEP_FACTOR ? STEP_FACTOR :step_li; step_li = step_li >256 ? 256 : step_li; int mc =-1; double tt = 2; for (i=0; i 0 ); return totalError(data,out,numEntries); } inline int getns(int partition[MAX_ENTRIES], int numEntries) { #ifdef USE_DBGTRACE DbgTrace(()); #endif int i,c; int id[MAX_ENTRIES]; for (i=0; ifabs(mean[l][k]- mean[(l+1) %3][k]) ? ni[l]:fabs(mean[l][k]- mean[(l+1) %3][k]) ; } }; for (l=0; l=Mi_) { printf("index error\n"); for (i=0; iMi ? index[k] :Mi; for (k=0; k 0 ? m[j] : 0 ; m[j]= m[j] < 255. ? m[j] : 255. ; #endif M[j]=floor( (mean[j]+direction[j]* (*step) *(Mi-s))/( (double) (1< 0 ? M[j] : 0 ; M[j]= M[j] < 255. ? M[j] : 255. ; #endif } int glue =1; for (j=0; j 0 ? pp[i][j] : 0 ; pp[i][j]= pp[i][j] < 255. ? pp[i][j] : 255. ; } for (k=0; k>1) ^ (p-1)^((p-1)>>1); r=p & (-p); if (q != r) printf("Gray code problem"); int di; di = (ss & q) ? -(1<< bits) : (1<=8) { i0++; q >>=3; }; for (q>>=1 ; q!=0; q >>=1) j0++; if (i0==0) { m[j0]+=di; #ifdef EP_CLUMP m[j0]= m[j0] > 0 ? m[j0] : 0 ; m[j0]= m[j0] < 255. ? m[j0] : 255. ; #endif } else { M[j0]+=di; #ifdef EP_CLUMP M[j0]= M[j0] > 0 ? M[j0] : 0 ; M[j0]= M[j0] < 255. ? M[j0] : 255. ; #endif } for (i=0; i<=Mi; i++) { pp[i][j0] = floor(m[j0]+(M[j0]-m[j0])* (i/ (double) Mi) + 0.5); pp[i][j0]= pp[i][j0] > 0 ? pp[i][j0] : 0 ; pp[i][j0]= pp[i][j0] < 255. ? pp[i][j0] : 255. ; } for (k=0; k> (2* bits - 8)); } void getRndRamp(int bits, double v, int size, double out[], int *parity, int range[2], int ep[] ) { #ifdef USE_DBGTRACE DbgTrace(()); #endif int m; m = (int)floor(v / (double) (1 << (8-bits))); m = m < 0 ? 0 :m ; m = m > (1<=0) { if (m < (1< i) { range[1] = i; } } else { range[0]=i+1; } m++; } } void getRndRampN(int bits[DIMENSION], double v[DIMENSION], int size, double out[ MAX_SHAKE_SIZE][DIMENSION], int parity[DIMENSION], int range[2][DIMENSION], int ep[ MAX_SHAKE_SIZE][DIMENSION],int bcc) { #ifdef USE_DBGTRACE DbgTrace(()); #endif static double out_[DIMENSION][MAX_SHAKE_SIZE]; int range_[DIMENSION][2]; int ep_[DIMENSION][MAX_SHAKE_SIZE]; int i,j; for (j=0; j1) { for (j=0; j Mi_) { printf("index error\n"); for (i=0; iMi ? index[k] :Mi; // shift/scale int p, q; int p0=-1,q0=-1; double ee = MAX_ENTRIES* 256.*256.*DIMENSION*8.; // 8 = slack if (Mi==0) { getRndRampN(bits, mean, 1/* size*/, epo+0, parity[0], range[0], ep[0],bcc) ; getRndRampN(bits, mean, 1/* size*/, epo+1, parity[1], range[1], ep[1],bcc) ; for (j=0; j255 ? 255: cv[i1]); } for (i1=0; i1< numEntries; i1++) t+=(cv[cidx[i1]]-data[i1][j])*(cv[cidx[i1]]-data[i1][j]); if (bcc) { if (t < e[(parity[0][j] ^ l0)& 1] [(parity[1][j] ^ l1)& 1][j] ) { e[(parity[0][j] ^ l0)& 1] [(parity[1][j] ^ l1)& 1][j] =t; best_ep[0][(parity[0][j] ^ l0)& 1] [(parity[1][j] ^ l1)& 1][j]=l0; best_ep[1][(parity[0][j] ^ l0)& 1] [(parity[1][j] ^ l1)& 1][j]=l1; } } else { if (t < e[0][0][j]) { e[0][0][j] =t; best_ep[0][0][0][j]=l0; best_ep[1][0][0][j]=l1; } } } } if (bcc) { double t[2][2]= {0,0,0,0}; double tt; int a,b,a0,b0; for (a=0; a<2; a++) for (b=0; b<2; b++) for (j=0; j t[a][b]) { a0=a; b0=b; tt = t[a][b]; } if (tt< ee) { ee = tt; p0=p; q0=q; for (j=0; j 0 ? pp[i][j] : 0 ; pp[i][j]= pp[i][j] < 255. ? pp[i][j] : 255. ; } for (k=0; k Mi_) { printf("index error\n"); for (i=0; iMi ? index[k] :Mi; // shift/scale int p, q; int p0=-1,q0=-1; double ee = MAX_ENTRIES* 256.*256.*DIMENSION*8.; // 8 = slack if (Mi==0) for (j=0; j 255 ?255:epo[0][j] ; epo[1][j]= epo[1][j] < 0 ?0:epo[1][j] ; epo[1][j]= epo[1][j] > 255 ?255:epo[1][j] ; } for (q=1; Mi!=0 && q*Mi <= Mi_; q++) for (p=q*Mi; p<=Mi_; p++) { //index * q + p-Mi*q int cidx[MAX_ENTRIES]; for (k=0; k255 ? 255: epd[0][i][j]; epd[1][i][j]=epd[1][i][j] <0 ? 0: epd[1][i][j]; epd[1][i][j]=epd[1][i][j] >255 ? 255: epd[1][i][j]; } { for (i=1; i=0; i--) { if (epd[0][i+1][j]==epd[0][i][j]) range[0][0][j]=i+1; if (epd[1][i+1][j]==epd[1][i][j]) range[1][0][j]=i+1; } } } #if 1 for (k=0; k255 ? 255: epd[0][i][j]; epd[1][i][j]=epd[1][i][j] <0 ? 0: epd[1][i][j]; epd[1][i][j]=epd[1][i][j] >255 ? 255: epd[1][i][j]; } { for (i=1; i=0; i--) { if (epd[0][i+1][j]==epd[0][i][j]) range[0][0][j]=i+1; if (epd[1][i+1][j]==epd[1][i][j]) range[1][0][j]=i+1; } } } } int best_ep [2][DIMENSION]; double e[DIMENSION]; int l0,l1; for (j=0; j255 ? 255: cv[i1]); } for (i1=0; i1< numEntries; i1++) t+=(cv[cidx[i1]]-data[i1][j])*(cv[cidx[i1]]-data[i1][j]); if (t < e[j]) { e[j] =t; best_ep[0][j]=l0; best_ep[1][j]=l1; } } } { double t=0; for (j=0; j 0 ? pp[i][j] : 0 ; pp[i][j]= pp[i][j] < 255. ? pp[i][j] : 255. ; } for (k=0; k1) { b--; bd/=2; } printf("Tight estimate, TOTAL %g\n",b); } int i,j,k; static double mean[DIMENSION]; int ok; int maxTry=10; static int index[MAX_ENTRIES]; static int index_r[MAX_ENTRIES]; for (i=0; i q1 ? fabs(direction[j]) : q1; } s /= (double) numEntries; t = t - s * s * (double) numEntries; t = (t == 0 ? 0. : 1/t); q=sqrt(q); *step=t*q; for (j=0; j=1.0001) printf("error\n"); } if (*step !=0) *step*=q1/q; double step_li=*step; static double dir_r[4][DIMENSION]; static double dir_step_r[2][4][DIMENSION]; // alternative for dir_r static double mean_r[8][DIMENSION]; static double mean_step_r[2][8][DIMENSION]; static double step_r[2]; if (step_li > 200000 ) {// bypass { NShakeCnt+=numEntries; for (i=0; i255 ? 255:mean_r[0][j]+MEAN_DIV*ii[j]; step_li = floor((step_li*STEP_FACTOR+.5)); step_li = step_li >256*STEP_FACTOR ? 256*STEP_FACTOR : step_li; int mc =-1; double tt = 2; for (i=0; i 0 ); return totalError(data,out,numEntries); }