Skip to content

AFNI/NIfTI Server

Sections
Personal tools
You are here: Home » AFNI » Documentation

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  * opts.c                                                                    *
00003  *                                                                           *
00004  *      Special C code to handle TUNEing options                             *
00005  *                                                                           *
00006  * EXPORTED PROCEDURES:                                                      *
00007  *      Tune_Init                                                            *
00008  *      CollectQuantStats                                                    *
00009  *                                                                           *
00010  *===========================================================================*/
00011 
00012 
00013 /*
00014  * Copyright (c) 1995 The Regents of the University of California.
00015  * All rights reserved.
00016  * 
00017  * Permission to use, copy, modify, and distribute this software and its
00018  * documentation for any purpose, without fee, and without written agreement is
00019  * hereby granted, provided that the above copyright notice and the following
00020  * two paragraphs appear in all copies of this software.
00021  * 
00022  * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
00023  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
00024  * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
00025  * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00026  * 
00027  * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
00028  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
00029  * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
00030  * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
00031  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
00032  */
00033 
00034 /*==============*
00035  * HEADER FILES *
00036  *==============*/
00037 
00038 #include <stdio.h>
00039 #include <string.h>
00040 #include "opts.h"
00041 /** #include <malloc.h> **/
00042 #include <math.h>
00043 
00044 /*==============*
00045  * EXTERNALS    *
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  * GLOBALS MADE HERE *
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  * Internal Prototypes*
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 /* define this as it too much of a pain to find toupper on different arch'es */
00097 #define ASCII_TOUPPER(c) ((c>='a') && (c<='z')) ? c-'a'+'A' : c
00098 
00099 /*=====================*
00100  * EXPORTED PROCEDURES *
00101  *=====================*/
00102 
00103 /*===========================================================================*
00104  *
00105  * Tune_Init
00106  *
00107  *     Do any setup needed before coding stream
00108  *
00109  * RETURNS:     nothing
00110  *
00111  * SIDE EFFECTS:  varies
00112  *
00113  *===========================================================================*/
00114 void Tune_Init()
00115 {
00116   int i;
00117 
00118   /* Just check for each, and do whats needed */
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  * ParseTuneParam
00152  *
00153  *     Handle the strings following TUNE
00154  *
00155  * RETURNS:     nothing
00156  *
00157  * SIDE EFFECTS:  varies
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  * Internals     *
00208  *===============*/
00209 
00210 /*===========================================================================*
00211  *
00212  * SetupCollectQuantStats
00213  *
00214  *     Setup variables to collect statistics on quantization values
00215  *
00216  * RETURNS:     nothing
00217  *
00218  * SIDE EFFECTS:    sets collect_quant and collect_quant_fp
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  * SetupKillDimAreas
00257  *
00258  *     Do a transform on small lum values
00259  *
00260  * RETURNS:     nothing
00261  *
00262  * SIDE EFFECTS:    sets kill_dim, kill_dim_break, kill_dim_end
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       /* Use defaults */
00279       kill_dim_break = 20;
00280       kill_dim_end   = 25;
00281     }
00282   }
00283   /* check values */
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  * SetupSquashSmall
00299  *
00300  *     Setup encoder to squash small changes in Y or Cr/Cb values
00301  *
00302  * RETURNS:     nothing
00303  *
00304  * SIDE EFFECTS:    sets squash_max_differences SquashMaxLum SquashMaxChr 
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     /* Only set one, do both */
00314     SquashMaxChr = SquashMaxLum;
00315   }
00316 }
00317 
00318 
00319 /*===========================================================================*
00320  *
00321  * SetupLocalDCT
00322  *
00323  *     Setup encoder to use DCT for rate-distortion estimat ein Psearches
00324  *
00325  * RETURNS:     nothing
00326  *
00327  * SIDE EFFECTS:    sets SearchCompareMode and
00328  *                        can change LocalDCTRateScale, LocalDCTDistortScale
00329  *
00330  *===========================================================================*/
00331 void SetupLocalDCT(charPtr)
00332 char *charPtr;
00333 {
00334   int num_scales=0;
00335 
00336   SearchCompareMode = LOCAL_DCT;
00337 
00338   /* Set scaling factors if present */
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  * SetupLaplace
00353  *
00354  *     Setup encoder to find distrubution for I-frames, and use for -snr
00355  *
00356  * RETURNS:     nothing
00357  *
00358  * SIDE EFFECTS:    sets DoLaplace, L1, L2, and Lambdas
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  * Mpost_UnQuantZigBlockLaplace
00403  *
00404  *      unquantize and zig-zag (decode) a single block, using the distrib to get vals
00405  *      Iblocks only now
00406  *
00407  * RETURNS:     nothing
00408  *
00409  * SIDE EFFECTS:    none
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     /* qtable[0] must be 8 */
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 /*printf("(%2.1lf-%2.1lf): old: %d vs %d\n",low,high,coeff,(int) mid);*/
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 }
 

Powered by Plone

This site conforms to the following standards: