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 }