Doxygen Source Code Documentation
        
Main Page   Alphabetical List   Data Structures   File List   Data Fields   Globals   Search   
opts.c
Go to the documentation of this file.00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 
00034 
00035 
00036 
00037 
00038 #include <stdio.h>
00039 #include <string.h>
00040 #include "opts.h"
00041 
00042 #include <math.h>
00043 
00044 
00045 
00046 
00047 
00048 extern char    outputFileName[];
00049 extern boolean pureDCT;
00050 extern int32   qtable[], niqtable[];
00051 extern int     ZAG[];
00052 extern boolean printSNR, decodeRefFrames;
00053 
00054 void init_idctref _ANSI_ARGS_((void));
00055 void init_fdct _ANSI_ARGS_((void));
00056 
00057 
00058 
00059 
00060 
00061 
00062 boolean tuneingOn = FALSE;
00063 int block_bound = 128;
00064 boolean collect_quant = FALSE;
00065 int collect_quant_detailed = 0;
00066 FILE *collect_quant_fp;
00067 int kill_dim = FALSE;
00068 int kill_dim_break, kill_dim_end;
00069 float kill_dim_slope;
00070 int SearchCompareMode = DEFAULT_SEARCH;
00071 boolean squash_small_differences = FALSE;
00072 int SquashMaxLum, SquashMaxChr;
00073 float LocalDCTRateScale = 1.0, LocalDCTDistortScale = 1.0;
00074 boolean IntraPBAllowed = TRUE;
00075 boolean WriteDistortionNumbers = FALSE;
00076 int collect_distortion_detailed = 0;
00077 FILE *distortion_fp;
00078 FILE *fp_table_rate[31], *fp_table_dist[31];
00079 boolean DoLaplace = FALSE;
00080 double **L1, **L2, **Lambdas;
00081 int LaplaceNum, LaplaceCnum;
00082 boolean BSkipBlocks = TRUE;
00083 
00084 
00085 
00086 
00087 void    SetupCollectQuantStats _ANSI_ARGS_((char *charPtr));
00088 void    SetupSquashSmall _ANSI_ARGS_ ((char *charPtr));
00089 void    SetupKillDimAreas _ANSI_ARGS_((char *charPtr));
00090 void    SetupLocalDCT _ANSI_ARGS_((char *charPtr));
00091 void    SetupWriteDistortions _ANSI_ARGS_((char *charPtr));
00092 void    SetupLaplace _ANSI_ARGS_((void));
00093 void    CalcLambdas  _ANSI_ARGS_((void));
00094 void    Mpost_UnQuantZigBlockLaplace _ANSI_ARGS_((FlatBlock in, Block out, int qscale, boolean iblock));
00095 
00096 
00097 #define ASCII_TOUPPER(c) ((c>='a') && (c<='z')) ? c-'a'+'A' : c
00098 
00099 
00100 
00101 
00102 
00103 
00104 
00105 
00106 
00107 
00108 
00109 
00110 
00111 
00112 
00113 
00114 void Tune_Init()
00115 {
00116   int i;
00117 
00118   
00119   if (collect_quant) {
00120     if (!pureDCT) {
00121       pureDCT = TRUE;
00122       init_idctref();
00123       init_fdct();
00124     }
00125     fprintf(collect_quant_fp, "# %s\n", outputFileName);
00126     fprintf(collect_quant_fp, "#");
00127     for (i=0; i<64; i++) 
00128       fprintf(collect_quant_fp, " %d", qtable[i]);
00129     fprintf(collect_quant_fp, "\n#");
00130     for (i=0; i<64; i++) 
00131       fprintf(collect_quant_fp, " %d", niqtable[i]);
00132     fprintf(collect_quant_fp, "\n# %d %d %d\n\n", 
00133             GetIQScale(), GetPQScale(), GetBQScale());
00134     
00135   }
00136 
00137   if (DoLaplace) {
00138     if (!pureDCT) {
00139       pureDCT = TRUE;
00140       init_idctref();
00141       init_fdct();
00142     }
00143     decodeRefFrames = TRUE;
00144     printSNR = TRUE;
00145   }
00146     
00147 }
00148 
00149 
00150 
00151 
00152 
00153 
00154 
00155 
00156 
00157 
00158 
00159 
00160 void ParseTuneParam(charPtr)
00161 char *charPtr;
00162 {
00163   switch (ASCII_TOUPPER(*charPtr)) {
00164   case 'B': 
00165     if (1 != sscanf(charPtr+2, "%d", &block_bound)) {
00166       fprintf(stderr, "Invalid tuning parameter (b) in parameter file.\n");
00167     }
00168     break;
00169   case 'C':
00170     SetupCollectQuantStats(charPtr+2);
00171     break;
00172   case 'D':
00173     SetupLocalDCT(SkipSpacesTabs(charPtr+1));
00174     break;
00175   case 'K':
00176     SetupKillDimAreas(SkipSpacesTabs(charPtr+1));
00177     break;
00178   case 'L':
00179     SetupLaplace();
00180     break;
00181   case 'N':
00182     SearchCompareMode = NO_DC_SEARCH;
00183     break;
00184   case 'Q':
00185     SearchCompareMode = DO_Mean_Squared_Distortion;
00186     break;
00187   case 'S':
00188     SetupSquashSmall(SkipSpacesTabs(charPtr+1));
00189     break;
00190   case 'W':
00191     SetupWriteDistortions(SkipSpacesTabs(charPtr+1));
00192     break;
00193   case 'U':
00194     BSkipBlocks = FALSE;
00195     break;
00196   case 'Z':
00197      IntraPBAllowed = FALSE;
00198     break;
00199   default:
00200     fprintf(stderr, "Unknown tuning (%s) in parameter file.\n",charPtr);
00201     break;
00202   }
00203 }
00204 
00205 
00206 
00207 
00208 
00209 
00210 
00211 
00212 
00213 
00214 
00215 
00216 
00217 
00218 
00219 
00220 
00221 void SetupCollectQuantStats(charPtr)
00222 char *charPtr;
00223 {
00224   char fname[256], *cp;
00225 
00226   cp = charPtr;
00227   while ( (*cp != ' ') && (*cp != '\t') && (*cp != '\n')) {
00228     cp++;
00229   }
00230 
00231   strncpy(fname, charPtr, cp-charPtr);
00232   fname[cp-charPtr] = '\0';
00233   collect_quant = TRUE;
00234   if ((collect_quant_fp = fopen(fname,"w")) == NULL) {
00235     fprintf(stderr, "Error opening %s for quant statistics\n", fname);
00236     fprintf(stderr, "Using stdout (ick!)\n");
00237     collect_quant_fp = stdout;
00238   }
00239 
00240   cp = SkipSpacesTabs(cp);
00241   if (*cp != '\n') {
00242     switch (*cp) {
00243     case 'c':
00244       collect_quant_detailed = 1;
00245       break;
00246     default:
00247       fprintf(stderr, "Unknown TUNE parameter setting format %s\n", cp);
00248     }}
00249 }
00250 
00251 
00252 
00253 
00254 
00255 
00256 
00257 
00258 
00259 
00260 
00261 
00262 
00263 
00264 
00265 void SetupKillDimAreas(charPtr)
00266 char *charPtr;
00267 {
00268   int items_scanned;
00269 
00270   kill_dim = TRUE;
00271   items_scanned = sscanf(charPtr, "%d %d %f", 
00272                          &kill_dim_break, &kill_dim_end, &kill_dim_slope);
00273   if (items_scanned != 3) {
00274     kill_dim_slope = 0.25;
00275     items_scanned = sscanf(charPtr, "%d %d", 
00276                            &kill_dim_break, &kill_dim_end);
00277     if (items_scanned != 2) {
00278       
00279       kill_dim_break = 20;
00280       kill_dim_end   = 25;
00281     }
00282   }
00283   
00284   if (kill_dim_break > kill_dim_end) {
00285     fprintf(stderr, "TUNE parameter k: break > end is illegal.\n");
00286     exit(-1);
00287   }
00288   if (kill_dim_slope < 0) {
00289     fprintf(stderr, "TUNE parameter k: slope < 0 is illegal.\n");
00290     exit(-1);
00291   }
00292 }
00293 
00294 
00295 
00296 
00297 
00298 
00299 
00300 
00301 
00302 
00303 
00304 
00305 
00306 
00307 void SetupSquashSmall(charPtr)
00308 char *charPtr;
00309 {
00310   squash_small_differences = TRUE;
00311 
00312   if (sscanf(charPtr, "%d %d", &SquashMaxLum, &SquashMaxChr) == 1) {
00313     
00314     SquashMaxChr = SquashMaxLum;
00315   }
00316 }
00317 
00318 
00319 
00320 
00321 
00322 
00323 
00324 
00325 
00326 
00327 
00328 
00329 
00330 
00331 void SetupLocalDCT(charPtr)
00332 char *charPtr;
00333 {
00334   int num_scales=0;
00335 
00336   SearchCompareMode = LOCAL_DCT;
00337 
00338   
00339   num_scales = sscanf(charPtr, "%f %f", &LocalDCTRateScale, &LocalDCTDistortScale);
00340   if (num_scales == 1) {
00341     fprintf(stderr, "Invalid number of scaling factors for local DCT\n");
00342     fprintf(stderr, "Must specify Rate Scale and Distorion scale (both floats)\n");
00343     fprintf(stderr, "Continuing with 1.0 1.0\n");
00344     LocalDCTRateScale = 1.0;
00345     LocalDCTDistortScale = 1.0;
00346   }
00347 }
00348 
00349 
00350 
00351 
00352 
00353 
00354 
00355 
00356 
00357 
00358 
00359 
00360 
00361 void SetupLaplace()
00362 {
00363   int i;
00364 
00365   DoLaplace = TRUE;
00366   LaplaceNum = 0;
00367   L1 = (double **)malloc(sizeof(double *)*3);
00368   L2 = (double **)malloc(sizeof(double *)*3);
00369   Lambdas = (double **)malloc(sizeof(double *)*3);
00370   if (L1 == NULL || L2 == NULL || Lambdas == NULL) {
00371     fprintf(stderr,"Out of memory!!!\n");
00372     exit(1);
00373   }
00374   for (i = 0; i < 3; i++) {
00375     L1[i] = (double *)calloc(64, sizeof(double));
00376     L2[i] = (double *)calloc(64, sizeof(double));
00377     Lambdas[i] = (double *)malloc(sizeof(double) * 64);
00378     if (L1[i] == NULL || L2[i] == NULL || Lambdas[i] == NULL) {
00379       fprintf(stderr,"Out of memory!!!\n");
00380       exit(1);
00381     }
00382   }
00383 }
00384 
00385 void CalcLambdas()
00386 {
00387   int i,j,n;
00388   double var;
00389   
00390   n = LaplaceNum;
00391   for (i = 0;   i < 3;  i++) {
00392     for (j = 0;  j < 64;  j++) {
00393       var = (n*L1[i][j] + L2[i][j]*L2[i][j]) / (n*(n-1));
00394       Lambdas[i][j] = sqrt(2.0) / sqrt(var);
00395     }
00396   }
00397 }
00398 
00399 
00400 
00401 
00402 
00403 
00404 
00405 
00406 
00407 
00408 
00409 
00410 
00411 
00412 void
00413 Mpost_UnQuantZigBlockLaplace(in, out, qscale, iblock)
00414     FlatBlock in;
00415     Block out;
00416     int qscale;
00417     boolean iblock;
00418 {
00419     register int index;
00420     int     position;
00421     register int            qentry;
00422     int     level, coeff;
00423     double low, high;
00424     double mid,lam;
00425 
00426     
00427     out[0][0] = (int16)(in[0] * 8);
00428     
00429     for ( index = 1;  index < DCTSIZE_SQ;  index++ ) {
00430       position = ZAG[index];
00431       level = in[index];
00432       
00433       if (level == 0) {
00434         ((int16 *)out)[position] = 0;
00435         continue;
00436       }
00437       qentry = qtable[position] * qscale;
00438       coeff = (level*qentry)/8;
00439       low = ((ABS(level)-.5)*qentry)/8;
00440       high = ((ABS(level)+.5)*qentry)/8;
00441       lam = Lambdas[LaplaceCnum][position];
00442       mid = (1.0/lam) * log(0.5*(exp(-lam*low)+exp(-lam*high)));
00443       mid = ABS(mid);
00444       if (mid - floor(mid) > .4999) {
00445         mid = ceil(mid);
00446       } else {
00447         mid = floor(mid);
00448       }
00449       if (level<0) {mid = -mid;}
00450 
00451       coeff = mid;
00452       if ( (coeff & 1) == 0 ) {
00453         if ( coeff < 0 ) {
00454           coeff++;
00455         } else if ( coeff > 0 ) {
00456           coeff--;
00457         }
00458       }
00459       ((int16 *)out)[position] = coeff;
00460     }
00461 }
00462 
00463 void
00464 SetupWriteDistortions(charPtr)
00465 char *charPtr;
00466 {
00467   char fname[256], *cp;
00468   int i;
00469 
00470   WriteDistortionNumbers = TRUE;
00471   cp = charPtr;
00472   while ( (*cp != ' ') && (*cp != '\t') && (*cp != '\n')) {
00473     cp++;
00474   }
00475 
00476   strncpy(fname, charPtr, cp-charPtr);
00477   fname[cp-charPtr] = '\0';
00478   collect_quant = TRUE;
00479   if ((distortion_fp = fopen(fname,"w")) == NULL) {
00480     fprintf(stderr, "Error opening %s for quant statistics\n", fname);
00481     fprintf(stderr, "Using stdout (ick!)\n");
00482     distortion_fp = stdout;
00483   }
00484 
00485   cp = SkipSpacesTabs(cp);
00486   if (*cp != '\n') {
00487     switch (*cp) {
00488     case 'c':
00489       collect_distortion_detailed = TRUE;
00490       break;
00491     case 't': {
00492       char scratch[256];
00493       collect_distortion_detailed = 2;
00494       for (i = 1;  i < 32;  i++) {
00495         sprintf(scratch, "%srate%d", fname, i);
00496         fp_table_rate[i-1] = fopen(scratch, "w");
00497         sprintf(scratch, "%sdist%d", fname, i);
00498         fp_table_dist[i-1] = fopen(scratch, "w");
00499         }}
00500       break;
00501     default:
00502       fprintf(stderr, "Unknown TUNE parameter setting format %s\n", cp);
00503     }}
00504 }  
00505 
00506 int mse(blk1, blk2)
00507 Block blk1, blk2;
00508 {
00509   register int index, error, tmp;
00510   int16 *bp1, *bp2;
00511 
00512   bp1 = (int16 *)blk1;
00513   bp2 = (int16 *)blk2;
00514   error = 0;
00515   for ( index = 0;  index < DCTSIZE_SQ;  index++ ) {
00516     tmp = *bp1++ - *bp2++;
00517     error += tmp*tmp;
00518   }
00519   return error;
00520 }