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
00039 #include "all.h"
00040 #include "mtypes.h"
00041 #include "frames.h"
00042 #include "frame.h"
00043 #include "fsize.h"
00044 #include "dct.h"
00045 #include "specifics.h"
00046 #include <stdio.h>
00047 #include <string.h>
00048 #include "prototypes.h"
00049
00050
00051
00052
00053
00054 #define CPP_LOC "/lib/cpp"
00055
00056
00057
00058
00059
00060 extern boolean specificsOn;
00061 extern char specificsFile[];
00062 extern char specificsDefines[];
00063 FrameSpecList *fsl;
00064
00065
00066
00067
00068
00069 void Parse_Specifics_File _ANSI_ARGS_((FILE *fp));
00070 void Parse_Specifics_File_v1 _ANSI_ARGS_((FILE *fp));
00071 void Parse_Specifics_File_v2 _ANSI_ARGS_((FILE *fp));
00072 FrameSpecList *MakeFslEntry _ANSI_ARGS_((void));
00073 void AddSlc _ANSI_ARGS_((FrameSpecList *c,int snum, int qs));
00074 Block_Specifics *AddBs _ANSI_ARGS_((FrameSpecList *c,int bnum,
00075 boolean rel, int qs));
00076 FrameSpecList *MakeFslEntry _ANSI_ARGS_((void));
00077 #define my_upper(c) (((c>='a') && (c<='z')) ? (c-'a'+'A') : c)
00078 #define CvtType(x) ReallyCvt(my_upper(x))
00079 #define ReallyCvt(x) (x=='I' ? 1 : (x=='P')?2: ((x=='B')?3:-1))
00080 #define SkipToSpace(lp) while ((*lp != ' ') && (*lp != '\n') && (*lp != '\0')) lp++
00081 #define EndString(lp) ((*lp == '\n') || (*lp == '\0'))
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142 static char version = -1;
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156 void Specifics_Init()
00157 {
00158 char command[1100];
00159 FILE *specificsFP;
00160
00161 sprintf(command, "/bin/rm -f %s.cpp", specificsFile);
00162 system(command);
00163 sprintf(command, "%s -P %s %s %s.cpp",
00164 CPP_LOC, specificsDefines, specificsFile, specificsFile);
00165 system(command);
00166 strcat(specificsFile, ".cpp");
00167 if ((specificsFP = fopen(specificsFile, "r")) == NULL) {
00168 fprintf(stderr, "Error with specifics file, cannot open %s\n", specificsFile);
00169 exit(1);
00170 }
00171 printf("Specifics file: %s\n", specificsFile);
00172 Parse_Specifics_File(specificsFP);
00173 sprintf(command, "/bin/rm -f %s.cpp", specificsFile);
00174 system(command);
00175
00176 }
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194 void Parse_Specifics_File(fp)
00195 FILE *fp;
00196 {
00197 char line[1024], *lp;
00198 int vers;
00199
00200 while ((fgets(line, 1023, fp)) != NULL) {
00201 lp = &line[0];
00202 while ((*lp == ' ') || (*lp == '\t')) lp++;
00203 if (( *lp == '#' ) || (*lp=='\n')) {
00204 continue;
00205 }
00206
00207 switch (my_upper(*lp)) {
00208 case 'F': case 'S': case 'B':
00209 fprintf(stderr, "Must specify version at beginning of specifics file\n");
00210 exit(0);
00211 break;
00212 case 'V':
00213 lp += 7;
00214 if (1 != sscanf(lp, "%d", &vers)) {
00215 fprintf(stderr," Improper version line in specs file: %s\n", line);
00216 } else {
00217 switch (vers) {
00218 case 1:
00219 version = vers;
00220 Parse_Specifics_File_v1(fp);
00221 break;
00222 case 2:
00223 version = vers;
00224 Parse_Specifics_File_v2(fp);
00225 break;
00226 default:
00227 fprintf(stderr, "Improper version line in specs file: %s\n", line);
00228 fprintf(stderr, "\tSpecifics file will be IGNORED.\n");
00229 specificsOn = FALSE;
00230 return;
00231 break;
00232 }}
00233 break;
00234 default:
00235 fprintf(stderr, "Specifics file: What? *%s*\n", line);
00236 break;
00237 }}
00238
00239 }
00240
00241
00242 void Parse_Specifics_File_v1(fp)
00243 FILE *fp;
00244 {
00245 char line[1024],*lp;
00246 FrameSpecList *current, *new;
00247 char typ;
00248 int fnum,snum, bnum, qs, newqs;
00249 int num_scanned;
00250
00251 fsl = MakeFslEntry();
00252 current = fsl;
00253
00254 while ((fgets(line,1023, fp)) != NULL) {
00255 lp = &line[0];
00256 while ((*lp == ' ') || (*lp == '\t')) lp++;
00257 if (( *lp == '#' ) || (*lp=='\n')) {
00258 continue;
00259 }
00260
00261 switch (my_upper(*lp)) {
00262 case 'F':
00263 lp += 6;
00264 sscanf(lp, "%d %c %d", &fnum, &typ, &qs);
00265 if (current->framenum != -1) {
00266 new=MakeFslEntry();
00267 current->next = new;
00268 current = new;
00269 }
00270 current->framenum = fnum;
00271 current->frametype = CvtType(typ);
00272 if (qs <= 0) qs = -1;
00273 current->qscale = qs;
00274 break;
00275 case 'S':
00276 lp += 6;
00277 sscanf(lp, "%d %d", &snum, &newqs);
00278 if (qs == newqs) break;
00279 qs = newqs;
00280 AddSlc(current, snum, qs);
00281 break;
00282 case 'B':
00283 lp += 6;
00284 num_scanned = sscanf(lp, "%d %d", &bnum, &newqs);
00285 if (qs == newqs) break;
00286 qs = newqs;
00287 AddBs(current, bnum, FALSE, qs);
00288 break;
00289 case 'V':
00290 fprintf(stderr, "Cannot specify version twice! Taking first (%d)\n", version);
00291 break;
00292 default:
00293 fprintf(stderr," What? *%s*\n", line);
00294 break;
00295 }}
00296
00297 }
00298
00299
00300 void Parse_Specifics_File_v2(fp)
00301 FILE *fp;
00302 {
00303 char line[1024], *lp;
00304 FrameSpecList *current, *new;
00305 char typ;
00306 int fnum, snum, bnum, qs, newqs;
00307 int num_scanned, fx=0, fy=0, sx=0, sy=0;
00308 char kind[100];
00309 Block_Specifics *new_blk;
00310 boolean relative;
00311
00312 fsl = MakeFslEntry();
00313 current = fsl;
00314
00315 while ((fgets(line,1023,fp))!=NULL) {
00316 lp = &line[0];
00317 while ((*lp == ' ') || (*lp == '\t')) lp++;
00318 if (( *lp == '#' ) || (*lp=='\n')) {
00319 continue;
00320 }
00321
00322 switch (my_upper(*lp)) {
00323 case 'F':
00324 lp += 6;
00325 sscanf(lp,"%d %c %d", &fnum, &typ, &qs);
00326 new = MakeFslEntry();
00327 if (current->framenum != -1) {
00328 current->next = new;
00329 current = new;
00330 }
00331 current->framenum = fnum;
00332 current->frametype = CvtType(typ);
00333 if (qs <= 0) qs = -1;
00334 current->qscale = qs;
00335 break;
00336 case 'S':
00337 lp += 6;
00338 sscanf(lp,"%d %d", &snum, &newqs);
00339 if (qs == newqs) break;
00340 qs = newqs;
00341 AddSlc(current, snum, qs);
00342 break;
00343 case 'B':
00344 lp += 6;
00345 num_scanned = 0;
00346 bnum = atoi(lp);
00347 SkipToSpace(lp);
00348 while ((*lp != '-') && (*lp != '+') &&
00349 ((*lp < '0') || (*lp > '9'))) lp++;
00350 relative = ((*lp == '-') || (*lp == '+'));
00351 newqs = atoi(lp);
00352 SkipToSpace(lp);
00353 if (EndString(lp)) {
00354 num_scanned = 2;
00355 } else {
00356 num_scanned = 2+sscanf(lp, "%s %d %d %d %d", kind, &fx, &fy, &sx, &sy);
00357 }
00358
00359 qs = newqs;
00360 new_blk = AddBs(current, bnum, relative, qs);
00361 if (num_scanned > 2) {
00362 BlockMV *tmp;
00363 tmp = (BlockMV *) malloc(sizeof(BlockMV));
00364 switch (num_scanned) {
00365 case 7:
00366 tmp->typ = TYP_BOTH;
00367 tmp->fx = fx;
00368 tmp->fy = fy;
00369 tmp->bx = sx;
00370 tmp->by = sy;
00371 new_blk->mv = tmp;
00372 break;
00373 case 3:
00374 tmp->typ = TYP_SKIP;
00375 new_blk->mv = tmp;
00376 break;
00377 case 5:
00378 if (my_upper(kind[0]) == 'B') {
00379 tmp->typ = TYP_BACK;
00380 tmp->bx = fx;
00381 tmp->by = fy;
00382 } else {
00383 tmp->typ = TYP_FORW;
00384 tmp->fx = fx;
00385 tmp->fy = fy;
00386 }
00387 new_blk->mv = tmp;
00388 break;
00389 default:
00390 fprintf(stderr,
00391 "Bug in specifics file! Skipping short/long entry: %s\n",line);
00392 break;
00393 }
00394 } else {
00395 new_blk->mv = (BlockMV *) NULL;
00396 }
00397
00398 break;
00399 case 'V':
00400 fprintf(stderr,
00401 "Cannot specify version twice! Taking first (%d).\n",
00402 version);
00403 break;
00404 default:
00405 printf("What? *%s*\n",line);
00406 break;
00407 }}
00408
00409 }
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426 FrameSpecList *MakeFslEntry()
00427 {
00428 FrameSpecList *fslp;
00429 fslp = (FrameSpecList *) malloc(sizeof(FrameSpecList));
00430 fslp->framenum = -1;
00431 fslp->slc = (Slice_Specifics *) NULL;
00432 fslp->bs = (Block_Specifics *) NULL;
00433 return fslp;
00434 }
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452 void AddSlc(c, snum, qs)
00453 FrameSpecList *c;
00454 int snum,qs;
00455 {
00456 Slice_Specifics *new;
00457 static Slice_Specifics *last;
00458
00459 new = (Slice_Specifics *) malloc(sizeof(Slice_Specifics));
00460 new->num = snum;
00461 new->qscale = qs;
00462 new->next = (Slice_Specifics *)NULL;
00463 if (c->slc == (Slice_Specifics *)NULL) {
00464 last = new;
00465 c->slc = new;
00466 } else {
00467 last->next = new;
00468 last = new;
00469 }
00470 }
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488 Block_Specifics *AddBs(c,bnum,rel,qs)
00489 FrameSpecList *c;
00490 boolean rel;
00491 int bnum,qs;
00492 {
00493 Block_Specifics *new;
00494 static Block_Specifics *last;
00495
00496 new = (Block_Specifics *) malloc(sizeof(Block_Specifics));
00497 new->num = bnum;
00498 if (qs == 0) rel = TRUE;
00499 new->relative = rel;
00500 new->qscale = qs;
00501 new->next = (Block_Specifics *)NULL;
00502 new->mv = (BlockMV *) NULL;
00503 if (c->bs == (Block_Specifics *)NULL) {
00504 last = new;
00505 c->bs = new;
00506 } else {
00507 last->next = new;
00508 last = new;
00509 }
00510 return new;
00511 }
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533 int SpecLookup(fn,typ,num,info,start_qs)
00534 int fn,typ,num;
00535 BlockMV **info;
00536 int start_qs;
00537 {
00538 static FrameSpecList *last = (FrameSpecList *) NULL;
00539 Slice_Specifics *sptr=(Slice_Specifics *) NULL;
00540 Block_Specifics *bptr=(Block_Specifics *) NULL;
00541 FrameSpecList *tmp;
00542 boolean found_it;
00543 static int leftovers = 0;
00544
00545 *info = (BlockMV * )NULL;
00546 if (last == (FrameSpecList *) NULL){
00547
00548 tmp = fsl;
00549 found_it = FALSE;
00550 while (tmp != (FrameSpecList *) NULL) {
00551 if (tmp->framenum == fn) {
00552 found_it = TRUE;
00553 break;
00554 } else tmp = tmp->next;
00555 }
00556 if (!found_it) return -1;
00557 last=tmp;
00558 } else {
00559 if (last->framenum != fn) {
00560
00561 if ((last->next != (FrameSpecList *) NULL) &&
00562 (last->next->framenum == fn)) {
00563 last = last->next;
00564 } else {
00565
00566
00567
00568 tmp = fsl;
00569 found_it = FALSE;
00570 while (tmp != (FrameSpecList *) NULL) {
00571 if (tmp->framenum==fn) {found_it = TRUE; break;}
00572 tmp = tmp->next;
00573 }
00574 if (!found_it) return -1;
00575 last = tmp;
00576 }
00577 }
00578 }
00579
00580 if (last == (FrameSpecList *) NULL) {
00581 fprintf(stderr, "PROGRAMMER ERROR: last is null!\n");
00582 return -1;
00583 }
00584 if (last->framenum!=fn) {
00585 fprintf(stderr, "PROGRAMMER ERROR: last has wrong number!\n");
00586 return -1;
00587 }
00588
00589 switch(typ) {
00590 case 0:
00591 leftovers = 0;
00592 #ifdef BLEAH
00593 printf("QSchange frame %d to %d\n", fn, last->qscale);
00594 #endif
00595 return last->qscale;
00596 break;
00597
00598 case 1:
00599 leftovers = 0;
00600
00601 if (last->slc == (Slice_Specifics *) NULL) return -1;
00602 for (sptr = last->slc; sptr != (Slice_Specifics *) NULL; sptr = sptr->next) {
00603 if (sptr->num == num) {
00604 #ifdef BLEAH
00605 printf("QSchange Slice %d.%d to %d\n", fn, num, sptr->qscale);
00606 #endif
00607 if (sptr->qscale == 0) return -1;
00608 return sptr->qscale;
00609 }
00610 }
00611 break;
00612
00613 case 2:
00614
00615 if (last->bs == (Block_Specifics *) NULL) {
00616 return -1;
00617 }
00618 for (bptr=last->bs; bptr != (Block_Specifics *) NULL; bptr=bptr->next) {
00619 if (bptr->num == num) {
00620 int new_one;
00621 #ifdef BLEAH
00622 printf("QSchange Block %d.%d to %d\n", fn, num, bptr->qscale);
00623 #endif
00624 *info = bptr->mv;
00625 if (bptr->relative) {
00626 if (bptr->qscale == 0) {
00627
00628 new_one = start_qs;
00629 } else {
00630 new_one = start_qs + bptr->qscale + leftovers;
00631 if (new_one < 1) {
00632 leftovers = new_one - 1;
00633 new_one = 1;
00634 } else if (new_one > 31) {
00635 leftovers = new_one - 31;
00636 new_one = 31;
00637 } else leftovers = 0;
00638 }}
00639 else {
00640 new_one = bptr->qscale;
00641 leftovers = 0;
00642 }
00643 return new_one;
00644 }
00645 }
00646 break;
00647 default:
00648 fprintf(stderr, "PROGRAMMER ERROR: reached unreachable code in SpecLookup\n");
00649 break;
00650 }
00651
00652 return -1;
00653 }
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667 int SpecTypeLookup(fn)
00668 int fn;
00669 {
00670 FrameSpecList *tmp;
00671
00672
00673 tmp = fsl;
00674 do {
00675 if (tmp->framenum == fn) break;
00676 else tmp = tmp->next;
00677 } while (tmp != (FrameSpecList *) NULL);
00678 if (tmp == (FrameSpecList *) NULL) {
00679 #ifdef BLEAH
00680 printf("Frame %d type not specified\n", fn);
00681 #endif
00682 return -1;
00683 }
00684 #ifdef BLEAH
00685 printf("Frame %d type set to %d\n", fn, tmp->frametype);
00686 #endif
00687 return tmp->frametype;
00688 }