gap.c
上传用户:weiliju62
上传日期:2007-01-06
资源大小:619k
文件大小:4k
源码类别:

SCSI/ASPI

开发平台:

MultiPlatform

  1. /***
  2.  * CopyPolicy: GNU Public License 2 applies
  3.  * Copyright (C) by Monty (xiphmont@mit.edu)
  4.  *
  5.  * Gapa analysis support code for paranoia
  6.  *
  7.  ***/
  8. #include "p_block.h"
  9. #include "cdda_paranoia.h"
  10. #include "gap.h"
  11. /**** Gap analysis code ***************************************************/
  12. long i_paranoia_overlap_r(size16 *buffA,size16 *buffB,
  13.   long offsetA, long offsetB){
  14.   long beginA=offsetA;
  15.   long beginB=offsetB;
  16.   for(;beginA>=0 && beginB>=0;beginA--,beginB--)
  17.     if(buffA[beginA]!=buffB[beginB])break;
  18.   beginA++;
  19.   beginB++;
  20.   
  21.   return(offsetA-beginA);
  22. }
  23. long i_paranoia_overlap_f(size16 *buffA,size16 *buffB,
  24.   long offsetA, long offsetB,
  25.   long sizeA,long sizeB){
  26.   long endA=offsetA;
  27.   long endB=offsetB;
  28.   
  29.   for(;endA<sizeA && endB<sizeB;endA++,endB++)
  30.     if(buffA[endA]!=buffB[endB])break;
  31.   
  32.   return(endA-offsetA);
  33. }
  34. int i_stutter_or_gap(size16 *A, size16 *B,long offA, long offB,
  35.      long gap){
  36.   long a1=offA;
  37.   long b1=offB;
  38.   
  39.   if(a1<0){
  40.     b1-=a1;
  41.     gap+=a1;
  42.     a1=0;
  43.   }
  44.   
  45.   return(memcmp(A+a1,B+b1,gap*2));
  46. }
  47. /* riftv is the first value into the rift -> or <- */
  48. void i_analyze_rift_f(size16 *A,size16 *B,
  49.       long sizeA, long sizeB,
  50.       long aoffset, long boffset, 
  51.       long *matchA,long *matchB,long *matchC){
  52.   
  53.   long apast=sizeA-aoffset;
  54.   long bpast=sizeB-boffset;
  55.   long i;
  56.   
  57.   *matchA=0, *matchB=0, *matchC=0;
  58.   
  59.   /* Look for three possible matches... (A) Ariftv->B, (B) Briftv->A and 
  60.      (c) AB->AB. */
  61.   
  62.   for(i=0;;i++){
  63.     if(i<bpast) /* A */
  64.       if(i_paranoia_overlap_f(A,B,aoffset,boffset+i,sizeA,sizeB)>=MIN_WORDS_RIFT){
  65. *matchA=i;
  66. break;
  67.       }
  68.     
  69.     if(i<apast){ /* B */
  70.       if(i_paranoia_overlap_f(A,B,aoffset+i,boffset,sizeA,sizeB)>=MIN_WORDS_RIFT){
  71. *matchB=i;
  72. break;
  73.       }
  74.       if(i<bpast) /* C */
  75. if(i_paranoia_overlap_f(A,B,aoffset+i,boffset+i,sizeA,sizeB)>=MIN_WORDS_RIFT){
  76.   *matchC=i;
  77.   break;
  78. }
  79.     }else
  80.       if(i>=bpast)break;
  81.     
  82.   }
  83.   
  84.   if(*matchA==0 && *matchB==0 && *matchC==0)return;
  85.   
  86.   if(*matchC)return;
  87.   if(*matchA){
  88.     if(i_stutter_or_gap(A,B,aoffset-*matchA,boffset,*matchA))
  89.       return;
  90.     *matchB=-*matchA; /* signify we need to remove n bytes from B */
  91.     *matchA=0;
  92.     return;
  93.   }else{
  94.     if(i_stutter_or_gap(B,A,boffset-*matchB,aoffset,*matchB))
  95.       return;
  96.     *matchA=-*matchB;
  97.     *matchB=0;
  98.     return;
  99.   }
  100. }
  101. /* riftv must be first even val of rift moving back */
  102. void i_analyze_rift_r(size16 *A,size16 *B,
  103.       long sizeA, long sizeB,
  104.       long aoffset, long boffset, 
  105.       long *matchA,long *matchB,long *matchC){
  106.   
  107.   long apast=aoffset+1;
  108.   long bpast=boffset+1;
  109.   long i;
  110.   
  111.   *matchA=0, *matchB=0, *matchC=0;
  112.   
  113.   /* Look for three possible matches... (A) Ariftv->B, (B) Briftv->A and 
  114.      (c) AB->AB. */
  115.   
  116.   for(i=0;;i++){
  117.     if(i<bpast) /* A */
  118.       if(i_paranoia_overlap_r(A,B,aoffset,boffset-i)>=MIN_WORDS_RIFT){
  119. *matchA=i;
  120. break;
  121.       }
  122.     if(i<apast){ /* B */
  123.       if(i_paranoia_overlap_r(A,B,aoffset-i,boffset)>=MIN_WORDS_RIFT){
  124. *matchB=i;
  125. break;
  126.       }      
  127.       if(i<bpast) /* C */
  128. if(i_paranoia_overlap_r(A,B,aoffset-i,boffset-i)>=MIN_WORDS_RIFT){
  129.   *matchC=i;
  130.   break;
  131. }
  132.     }else
  133.       if(i>=bpast)break;
  134.     
  135.   }
  136.   
  137.   if(*matchA==0 && *matchB==0 && *matchC==0)return;
  138.   
  139.   if(*matchC)return;
  140.   
  141.   if(*matchA){
  142.     if(i_stutter_or_gap(A,B,aoffset+1,boffset-*matchA+1,*matchA))
  143.       return;
  144.     *matchB=-*matchA; /* signify we need to remove n bytes from B */
  145.     *matchA=0;
  146.     return;
  147.   }else{
  148.     if(i_stutter_or_gap(B,A,boffset+1,aoffset-*matchB+1,*matchB))
  149.       return;
  150.     *matchA=-*matchB;
  151.     *matchB=0;
  152.     return;
  153.   }
  154. }
  155. void  analyze_rift_silence_f(size16 *A,size16 *B,long sizeA,long sizeB,
  156.      long aoffset, long boffset,
  157.      long *matchA, long *matchB){
  158.   *matchA=-1;
  159.   *matchB=-1;
  160.   sizeA=min(sizeA,aoffset+MIN_WORDS_RIFT);
  161.   sizeB=min(sizeB,boffset+MIN_WORDS_RIFT);
  162.   aoffset++;
  163.   boffset++;
  164.   while(aoffset<sizeA){
  165.     if(A[aoffset]!=A[aoffset-1]){
  166.       *matchA=0;
  167.       break;
  168.     }
  169.     aoffset++;
  170.   }
  171.   while(boffset<sizeB){
  172.     if(B[boffset]!=B[boffset-1]){
  173.       *matchB=0;
  174.       break;
  175.     }
  176.     boffset++;
  177.   }
  178. }