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 }