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

SCSI/ASPI

开发平台:

MultiPlatform

  1. /***
  2.  * CopyPolicy: GNU Public License 2 applies
  3.  * Copyright (C) by Monty (xiphmont@mit.edu)
  4.  *
  5.  * Toplevel file for the paranoia abstraction over the cdda lib 
  6.  *
  7.  ***/
  8. /* immediate todo:: */
  9. /* Allow disabling of root fixups? */ 
  10. /* Dupe bytes are creeping into cases that require greater overlap
  11.    *than a single fragment can provide.  We need to check against a
  12.    *larger area* (+/-32 sectors of root?) to better eliminate
  13.    *dupes. Of course this leads to other problems... Is it actually a
  14.    *practically solvable problem? */
  15. /* Bimodal overlap distributions break us. */
  16. /* scratch detection/tolerance not implemented yet */
  17. /***************************************************************
  18.   Da new shtick: verification now a two-step assymetric process.
  19.   
  20.   A single 'verified/reconstructed' data segment cache, and then the
  21.   multiple fragment cache 
  22.   verify a newly read block against previous blocks; do it only this
  23.   once. We maintain a list of 'verified sections' from these matches.
  24.   We then glom these verified areas into a new data buffer.
  25.   Defragmentation fixups are allowed here alone.
  26.   We also now track where read boundaries actually happened; do not
  27.   verify across matching boundaries.
  28.   **************************************************************/
  29. /***************************************************************
  30.   Silence case continues to dog us; let's try the following to put the
  31.   damned thing to rest (stage 2 mods only):
  32.   a) at root fixup stage: past the rift is one silence and the other
  33.      signal?  Believe the signal.
  34.   b) if signal is in root, truncate the fragment.  if the signal is in
  35.      the fragment, truncate root
  36.   **************************************************************/
  37. #include <stdlib.h>
  38. #include <unistd.h>
  39. #include <stdio.h>
  40. #include <string.h>
  41. #include <math.h>
  42. #include "../dao/cdda_interface.h"
  43. #include "p_block.h"
  44. #include "cdda_paranoia.h"
  45. #include "overlap.h"
  46. #include "gap.h"
  47. #include "isort.h"
  48. static inline long re(root_block *root){
  49.   if(!root)return(-1);
  50.   if(!root->vector)return(-1);
  51.   return(ce(root->vector));
  52. }
  53. static inline long rb(root_block *root){
  54.   if(!root)return(-1);
  55.   if(!root->vector)return(-1);
  56.   return(cb(root->vector));
  57. }
  58. static inline long rs(root_block *root){
  59.   if(!root)return(-1);
  60.   if(!root->vector)return(-1);
  61.   return(cs(root->vector));
  62. }
  63. static inline size16 *rv(root_block *root){
  64.   if(!root)return(NULL);
  65.   if(!root->vector)return(NULL);
  66.   return(cv(root->vector));
  67. }
  68. #define rc(r) (r->vector)
  69. /**** matching and analysis code *****************************************/
  70. static inline long i_paranoia_overlap(size16 *buffA,size16 *buffB,
  71.        long offsetA, long offsetB,
  72.        long sizeA,long sizeB,
  73.        long *ret_begin, long *ret_end){
  74.   long beginA=offsetA,endA=offsetA;
  75.   long beginB=offsetB,endB=offsetB;
  76.   for(;beginA>=0 && beginB>=0;beginA--,beginB--)
  77.     if(buffA[beginA]!=buffB[beginB])break;
  78.   beginA++;
  79.   beginB++;
  80.   
  81.   for(;endA<sizeA && endB<sizeB;endA++,endB++)
  82.     if(buffA[endA]!=buffB[endB])break;
  83.   
  84.   if(ret_begin)*ret_begin=beginA;
  85.   if(ret_end)*ret_end=endA;
  86.   return(endA-beginA);
  87. }
  88. static inline long i_paranoia_overlap2(size16 *buffA,size16 *buffB,
  89.        char *flagsA,char *flagsB,
  90.        long offsetA, long offsetB,
  91.        long sizeA,long sizeB,
  92.        long *ret_begin, long *ret_end){
  93.   long beginA=offsetA,endA=offsetA;
  94.   long beginB=offsetB,endB=offsetB;
  95.   
  96.   for(;beginA>=0 && beginB>=0;beginA--,beginB--){
  97.     if(buffA[beginA]!=buffB[beginB])break;
  98.     /* don't allow matching across matching sector boundaries */
  99.     /* don't allow matching through known missing data */
  100.     if((flagsA[beginA]&flagsB[beginB]&1)){
  101.       beginA--;
  102.       beginB--;
  103.       break;
  104.     }
  105.     if((flagsA[beginA]&2)|| (flagsB[beginB]&2))break;
  106.   }
  107.   beginA++;
  108.   beginB++;
  109.   
  110.   for(;endA<sizeA && endB<sizeB;endA++,endB++){
  111.     if(buffA[endA]!=buffB[endB])break;
  112.     /* don't allow matching across matching sector boundaries */
  113.     if((flagsA[endA]&flagsB[endB]&1) &&endA!=beginA){
  114.       break;
  115.     }
  116.     /* don't allow matching through known missing data */
  117.     if((flagsA[endA]&2)||(flagsB[endB]&2))break;
  118.   }
  119.   if(ret_begin)*ret_begin=beginA;
  120.   if(ret_end)*ret_end=endA;
  121.   return(endA-beginA);
  122. }
  123. /* Top level of the first stage matcher */
  124. /* We match each analysis point of new to the preexisting blocks
  125. recursively.  We can also optionally maintain a list of fragments of
  126. the preexisting block that didn't match anything, and match them back
  127. afterward. */
  128. #define OVERLAP_ADJ (MIN_WORDS_OVERLAP/2-1)
  129. static inline long do_const_sync(c_block *A,
  130.  sort_info *B,char *flagB,
  131.  long posA,long posB,
  132.  long *begin,long *end,long *offset){
  133.   char *flagA=A->flags;
  134.   long ret=0;
  135.   if(flagB==NULL)
  136.     ret=i_paranoia_overlap(cv(A),iv(B),posA,posB,
  137.    cs(A),is(B),begin,end);
  138.   else
  139.     if((flagB[posB]&2)==0)
  140.       ret=i_paranoia_overlap2(cv(A),iv(B),flagA,flagB,posA,posB,cs(A),
  141.       is(B),begin,end);
  142.   if(ret>MIN_WORDS_SEARCH){
  143.     *offset=+(posA+cb(A))-(posB+ib(B));
  144.     *begin+=cb(A);
  145.     *end+=cb(A);
  146.     return(ret);
  147.   }
  148.   
  149.   return(0);
  150. }
  151. /* post is w.r.t. B.  9.3 is a bit different; in stage one, we post
  152.    from new.  In stage 2 we post from root. Begin, end, offset count
  153.    from B's frame of reference */
  154. static inline long try_sort_sync(cdrom_paranoia *p,
  155.  sort_info *A,char *Aflags,
  156.  c_block *B,
  157.  long post,long *begin,long *end,
  158.  long *offset,void (*callback)(long,int)){
  159.   
  160.   long dynoverlap=p->dynoverlap;
  161.   sort_link *ptr=NULL;
  162.   char *Bflags=B->flags;
  163.   /* block flag matches 0x02 (unmatchable) */
  164.   if(Bflags==NULL || (Bflags[post-cb(B)]&2)==0){
  165.     /* always try absolute offset zero first! */
  166.     {
  167.       long zeropos=post-ib(A);
  168.       if(zeropos>=0 && zeropos<is(A)){
  169. if(cv(B)[post-cb(B)]==iv(A)[zeropos]){
  170.   if(do_const_sync(B,A,Aflags,
  171.    post-cb(B),zeropos,
  172.    begin,end,offset)){
  173.     
  174.     offset_add_value(p,&(p->stage1),*offset,callback);
  175.     
  176.     return(1);
  177.   }
  178. }
  179.       }
  180.     }
  181.   }else
  182.     return(0);
  183.   
  184.   ptr=sort_getmatch(A,post-ib(A),dynoverlap,cv(B)[post-cb(B)]);
  185.   
  186.   while(ptr){
  187.     
  188.     if(do_const_sync(B,A,Aflags,
  189.      post-cb(B),ipos(A,ptr),
  190.      begin,end,offset)){
  191.       offset_add_value(p,&(p->stage1),*offset,callback);
  192.       return(1);
  193.     }
  194.     ptr=sort_nextmatch(A,ptr);
  195.   }
  196.   
  197.   *begin=-1;
  198.   *end=-1;
  199.   *offset=-1;
  200.   return(0);
  201. }
  202. static inline void stage1_matched(c_block *old,c_block *new,
  203.  long matchbegin,long matchend,
  204.  long matchoffset,void (*callback)(long,int)){
  205.   long i;
  206.   long oldadjbegin=matchbegin-cb(old);
  207.   long oldadjend=matchend-cb(old);
  208.   long newadjbegin=matchbegin-matchoffset-cb(new);
  209.   long newadjend=matchend-matchoffset-cb(new);
  210.   
  211.   if(matchbegin-matchoffset<=cb(new) ||
  212.      matchbegin<=cb(old) ||
  213.      (new->flags[newadjbegin]&1) ||
  214.      (old->flags[oldadjbegin]&1)){
  215.     if(matchoffset)
  216.       (*callback)(matchbegin,PARANOIA_CB_FIXUP_EDGE);
  217.   }else
  218.     (*callback)(matchbegin,PARANOIA_CB_FIXUP_ATOM);
  219.   
  220.   if(matchend-matchoffset>=ce(new) ||
  221.      (new->flags[newadjend]&1) ||
  222.      matchend>=ce(old) ||
  223.      (old->flags[oldadjend]&1)){
  224.     if(matchoffset)
  225.       (*callback)(matchend,PARANOIA_CB_FIXUP_EDGE);
  226.   }else
  227.     (*callback)(matchend,PARANOIA_CB_FIXUP_ATOM);
  228.   
  229.   /* Mark the verification flags.  Don't mark the first or
  230.      last OVERLAP/2 elements so that overlapping fragments
  231.      have to overlap by OVERLAP to actually merge. We also
  232.      remove elements from the sort such that later sorts do
  233.      not have to sift through already matched data */
  234.   
  235.   newadjbegin+=OVERLAP_ADJ;
  236.   newadjend-=OVERLAP_ADJ;
  237.   for(i=newadjbegin;i<newadjend;i++)
  238.     new->flags[i]|=4; /* mark verified */
  239.   oldadjbegin+=OVERLAP_ADJ;
  240.   oldadjend-=OVERLAP_ADJ;
  241.   for(i=oldadjbegin;i<oldadjend;i++)
  242.     old->flags[i]|=4; /* mark verified */
  243.     
  244. }
  245. static long i_iterate_stage1(cdrom_paranoia *p,c_block *old,c_block *new,
  246.      void(*callback)(long,int)){
  247.   long matchbegin=-1,matchend=-1,matchoffset;
  248.   /* we no longer try to spread the stage one search area by dynoverlap */
  249.   long searchend=min(ce(old),ce(new));
  250.   long searchbegin=max(cb(old),cb(new));
  251.   long searchsize=searchend-searchbegin;
  252.   sort_info *i=p->sortcache;
  253.   long ret=0;
  254.   long j;
  255.   long tried=0,matched=0;
  256.   if(searchsize<=0)return(0);
  257.   
  258.   /* match return values are in terms of the new vector, not old */
  259.   for(j=searchbegin;j<searchend;j+=23){
  260.     if((new->flags[j-cb(new)]&6)==0){      
  261.       tried++;
  262.       if(try_sort_sync(p,i,new->flags,old,j,&matchbegin,&matchend,&matchoffset,
  263.        callback)==1){
  264. matched+=matchend-matchbegin;
  265. stage1_matched(old,new,matchbegin,matchend,matchoffset,callback);
  266. ret++;
  267. if(matchend-1>j)j=matchend-1;
  268.       }
  269.     }
  270.   }
  271. #ifdef NOISY 
  272.   fprintf(stderr,"iterate_stage1: search area=%ld[%ld-%ld] tried=%ld matched=%ld spans=%ldn",
  273.   searchsize,searchbegin,searchend,tried,matched,ret);
  274. #endif
  275.   return(ret);
  276. }
  277. static long i_stage1(cdrom_paranoia *p,c_block *new,
  278.      void(*callback)(long,int)){
  279.   long size=cs(new);
  280.   c_block *ptr=c_last(p);
  281.   int ret=0;
  282.   long begin=0,end;
  283.   
  284.   if(ptr)sort_setup(p->sortcache,cv(new),&cb(new),cs(new),
  285.     cb(new),ce(new));
  286.   while(ptr && ptr!=new){
  287.     (*callback)(cb(new),PARANOIA_CB_VERIFY);
  288.     i_iterate_stage1(p,ptr,new,callback);
  289.     ptr=c_prev(ptr);
  290.   }
  291.   /* parse the verified areas of new into v_fragments */
  292.   
  293.   begin=0;
  294.   while(begin<size){
  295.     for(;begin<size;begin++)if(new->flags[begin]&4)break;
  296.     for(end=begin;end<size;end++)if((new->flags[end]&4)==0)break;
  297.     if(begin>=size)break;
  298.     
  299.     ret++;
  300.     new_v_fragment(p,new,cb(new)+max(0,begin-OVERLAP_ADJ),
  301.    cb(new)+min(size,end+OVERLAP_ADJ),
  302.    (end+OVERLAP_ADJ>=size && new->lastsector));
  303.     begin=end;
  304.   }
  305.   
  306.   return(ret);
  307. }
  308. /* reconcile v_fragments to root buffer.  Free if matched, fragment/fixup root
  309.    if necessary */
  310. typedef struct sync_result {
  311.   long offset;
  312.   long begin;
  313.   long end;
  314. } sync_result;
  315. static long i_iterate_stage2(cdrom_paranoia *p,
  316.      v_fragment *v,int multi,
  317.      sync_result *r,void(*callback)(long,int)){
  318.   root_block *root=&(p->root);
  319.   long matchbegin=-1,matchend=-1,offset;
  320.   long fbv,fev;
  321.   
  322. #ifdef NOISY
  323.       fprintf(stderr,"Stage 2 search: fbv=%ld fev=%ldn",fb(v),fe(v));
  324. #endif
  325.   if(min(fe(v)+p->dynoverlap,re(root))-
  326.     max(fb(v)-p->dynoverlap,rb(root))<=0)return(0);
  327.   (*callback)(fb(v),PARANOIA_CB_VERIFY);
  328.   /* just a bit of v unless multi; determine the correct area */
  329.   fbv=max(fb(v),rb(root)-p->dynoverlap);
  330.   /* stage 2 silence handling mod A,B */
  331.   if(!multi){
  332.     /* we want to avoid zeroes */
  333.     while(fbv<fe(v) && fv(v)[fbv-fb(v)]==0)fbv++;
  334.     if(fbv==fe(v))return(0);
  335.     fev=min(min(fbv+256,re(root)+p->dynoverlap),fe(v));
  336.   }else{
  337.     fev=min(re(root)+p->dynoverlap,fe(v));
  338.   }
  339.   
  340.   {
  341.     /* spread the search area a bit.  We post from root, so containment
  342.        must strictly adhere to root */
  343.     long searchend=min(fev+p->dynoverlap,re(root));
  344.     long searchbegin=max(fbv-p->dynoverlap,rb(root));
  345.     sort_info *i=p->sortcache;
  346.     long j;
  347.     
  348.     sort_setup(i,fv(v),&fb(v),fs(v),fbv,fev);
  349.     
  350.     for(j=searchbegin;j<searchend;j+=23){
  351.       if(!multi)
  352. while(j<searchend && rv(root)[j-rb(root)]==0)j++;
  353.       if(j==searchend)break;
  354.      
  355.       if(try_sort_sync(p,i,NULL,rc(root),j,
  356.        &matchbegin,&matchend,&offset,callback)){
  357. r->begin=matchbegin;
  358. r->end=matchend;
  359. r->offset=-offset;
  360. if(offset)(*callback)(r->begin,PARANOIA_CB_FIXUP_EDGE);
  361. return(1);
  362.       }
  363.     }
  364.   }
  365.   
  366.   return(0);
  367. }
  368. static long i_stage2_each(root_block *root, v_fragment *v,
  369.   int freeit,int multi,
  370.   void(*callback)(long,int)){
  371.   cdrom_paranoia *p=v->p;
  372.   long dynoverlap=p->dynoverlap/2*2;
  373.   
  374.   if(!v || !v->one)return(0);
  375.   if(!rv(root)){
  376.     return(0);
  377.   }else{
  378.     sync_result r;
  379.     if(i_iterate_stage2(p,v,multi,&r,callback)){
  380.       long begin=r.begin-rb(root);
  381.       long end=r.end-rb(root);
  382.       long offset=r.begin+r.offset-fb(v)-begin;
  383.       long temp;
  384.       c_block *l=NULL;
  385.       /* we have a match! We don't rematch off rift, we chase the
  386.  match all the way to both extremes doing rift analysis. */
  387. #ifdef NOISY
  388.       fprintf(stderr,"Stage 2 matchn");
  389. #endif
  390.       /* chase backward */
  391.       /* note that we don't extend back right now, only forward. */
  392.       while((begin+offset>0 && begin>0)){
  393. long matchA=0,matchB=0,matchC=0;
  394. long beginL=begin+offset;
  395. if(l==NULL){
  396.   size16 *buff=malloc(fs(v)*sizeof(size16));
  397.   l=c_alloc(buff,fb(v),fs(v));
  398.   memcpy(buff,fv(v),fs(v)*sizeof(size16));
  399. }
  400. i_analyze_rift_r(rv(root),cv(l),
  401.  rs(root),cs(l),
  402.  begin-1,beginL-1,
  403.  &matchA,&matchB,&matchC);
  404. #ifdef NOISY
  405. fprintf(stderr,"matching rootR: matchA:%ld matchB:%ld matchC:%ldn",
  406. matchA,matchB,matchC);
  407. #endif
  408. if(matchA){
  409.   /* a problem with root */
  410.   if(matchA>0){
  411.     /* dropped bytes; add back from v */
  412.     (*callback)(begin+rb(root)-1,PARANOIA_CB_FIXUP_DROPPED);
  413.     if(rb(root)+begin<p->root.returnedlimit)
  414.       break;
  415.     else{
  416.       c_insert(rc(root),begin,cv(l)+beginL-matchA,
  417.  matchA);
  418.       offset-=matchA;
  419.       begin+=matchA;
  420.       end+=matchA;
  421.     }
  422.   }else{
  423.     /* duplicate bytes; drop from root */
  424.     (*callback)(begin+rb(root)-1,PARANOIA_CB_FIXUP_DUPED);
  425.     if(rb(root)+begin+matchA<p->root.returnedlimit) 
  426.       break;
  427.     else{
  428.       c_remove(rc(root),begin+matchA,-matchA);
  429.       offset-=matchA;
  430.       begin+=matchA;
  431.       end+=matchA;
  432.     }
  433.   }
  434. }else if(matchB){
  435.   /* a problem with the fragment */
  436.   if(matchB>0){
  437.     /* dropped bytes */
  438.     (*callback)(begin+rb(root)-1,PARANOIA_CB_FIXUP_DROPPED);
  439.     c_insert(l,beginL,rv(root)+begin-matchB,
  440.  matchB);
  441.     offset+=matchB;
  442.   }else{
  443.     /* duplicate bytes */
  444.     (*callback)(begin+rb(root)-1,PARANOIA_CB_FIXUP_DUPED);
  445.     c_remove(l,beginL+matchB,-matchB);
  446.     offset+=matchB;
  447.   }
  448. }else if(matchC){
  449.   /* Uhh... problem with both */
  450.   
  451.   /* Set 'disagree' flags in root */
  452.   if(rb(root)+begin-matchC<p->root.returnedlimit)
  453.     break;
  454.   c_overwrite(rc(root),begin-matchC,
  455. cv(l)+beginL-matchC,matchC);
  456.   
  457. }else{
  458.   /* do we have a mismatch due to silence beginning/end case? */
  459.   /* in the 'chase back' case, we don't do anything. */
  460.   /* Did not determine nature of difficulty... 
  461.      report and bail */
  462.     
  463.   /*RRR(*callback)(post,PARANOIA_CB_XXX);*/
  464.   break;
  465. }
  466. /* not the most efficient way, but it will do for now */
  467. beginL=begin+offset;
  468. i_paranoia_overlap(rv(root),cv(l),
  469.    begin,beginL,
  470.    rs(root),cs(l),
  471.    &begin,&end);
  472.       }
  473.       
  474.       /* chase forward */
  475.       temp=l?cs(l):fs(v);
  476.       while(end+offset<temp && end<rs(root)){
  477. long matchA=0,matchB=0,matchC=0;
  478. long beginL=begin+offset;
  479. long endL=end+offset;
  480. if(l==NULL){
  481.   size16 *buff=malloc(fs(v)*sizeof(size16));
  482.   l=c_alloc(buff,fb(v),fs(v));
  483.   memcpy(buff,fv(v),fs(v)*sizeof(size16));
  484. }
  485. i_analyze_rift_f(rv(root),cv(l),
  486.  rs(root),cs(l),
  487.  end,endL,
  488.  &matchA,&matchB,&matchC);
  489. #ifdef NOISY
  490. fprintf(stderr,"matching rootF: matchA:%ld matchB:%ld matchC:%ldn",
  491. matchA,matchB,matchC);
  492. #endif
  493. if(matchA){
  494.   /* a problem with root */
  495.   if(matchA>0){
  496.     /* dropped bytes; add back from v */
  497.     (*callback)(end+rb(root),PARANOIA_CB_FIXUP_DROPPED);
  498.     if(end+rb(root)<p->root.returnedlimit)
  499.       break;
  500.     c_insert(rc(root),end,cv(l)+endL,matchA);
  501.   }else{
  502.     /* duplicate bytes; drop from root */
  503.     (*callback)(end+rb(root),PARANOIA_CB_FIXUP_DUPED);
  504.     if(end+rb(root)<p->root.returnedlimit)
  505.       break;
  506.     c_remove(rc(root),end,-matchA);
  507.   }
  508. }else if(matchB){
  509.   /* a problem with the fragment */
  510.   if(matchB>0){
  511.     /* dropped bytes */
  512.     (*callback)(end+rb(root),PARANOIA_CB_FIXUP_DROPPED);
  513.     c_insert(l,endL,rv(root)+end,matchB);
  514.   }else{
  515.     /* duplicate bytes */
  516.     (*callback)(end+rb(root),PARANOIA_CB_FIXUP_DUPED);
  517.     c_remove(l,endL,-matchB);
  518.   }
  519. }else if(matchC){
  520.   /* Uhh... problem with both */
  521.   
  522.   /* Set 'disagree' flags in root */
  523.   if(end+rb(root)<p->root.returnedlimit)
  524.     break;
  525.   c_overwrite(rc(root),end,cv(l)+endL,matchC);
  526. }else{
  527.   analyze_rift_silence_f(rv(root),cv(l),
  528.  rs(root),cs(l),
  529.  end,endL,
  530.  &matchA,&matchB);
  531.   if(matchA){
  532.     /* silence in root */
  533.     /* Can only do this if we haven't already returned data */
  534.     if(end+rb(root)>=p->root.returnedlimit){
  535.       c_remove(rc(root),end,-1);
  536.     }
  537.   }else if(matchB){
  538.     /* silence in fragment; lose it */
  539.     
  540.     if(l)i_cblock_destructor(l);
  541.     if(freeit)free_v_fragment(v);
  542.     return(1);
  543.   }else{
  544.     /* Could not determine nature of difficulty... 
  545.        report and bail */
  546.     
  547.     /*RRR(*callback)(post,PARANOIA_CB_XXX);*/
  548.   }
  549.   break;
  550. }
  551. /* not the most efficient way, but it will do for now */
  552. i_paranoia_overlap(rv(root),cv(l),
  553.    begin,beginL,
  554.    rs(root),cs(l),
  555.    NULL,&end);
  556.       }
  557.       /* if this extends our range, let's glom */
  558.       {
  559. long sizeA=rs(root);
  560. long sizeB;
  561. long vecbegin;
  562. size16 *vector;
  563.   
  564. if(l){
  565.   sizeB=cs(l);
  566.   vector=cv(l);
  567.   vecbegin=cb(l);
  568. }else{
  569.   sizeB=fs(v);
  570.   vector=fv(v);
  571.   vecbegin=fb(v);
  572. }
  573. if(sizeB-offset>sizeA || v->lastsector){   
  574.   if(v->lastsector){
  575.     root->lastsector=1;
  576.   }
  577.   
  578.   if(end<sizeA)c_remove(rc(root),end,-1);
  579.   
  580.   if(sizeB-offset-end)c_append(rc(root),vector+end+offset,
  581.  sizeB-offset-end);
  582.   
  583.   /* add offset into dynoverlap stats */
  584.   offset_add_value(p,&p->stage2,offset+vecbegin-rb(root),callback);
  585. }
  586.       }
  587.       if(l)i_cblock_destructor(l);
  588.       if(freeit)free_v_fragment(v);
  589.       return(1);
  590.       
  591.     }else{
  592.       /* D'oh.  No match.  What to do with the fragment? */
  593.       if(fe(v)+dynoverlap<re(root)){
  594. /* It *should* have matched.  No good; free it. */
  595. if(freeit)free_v_fragment(v);
  596.       }
  597.       /* otherwise, we likely want this for an upcoming match */
  598.       /* we don't free the sort info (if it was collected) */
  599.       return(0);
  600.       
  601.     }
  602.   }
  603. }
  604. static int i_init_root(root_block *root, v_fragment *v,long begin,
  605.        void(*callback)(long,int)){
  606.   if(fb(v)<=begin && fe(v)>begin){
  607.     
  608.     root->lastsector=v->lastsector;
  609.     root->returnedlimit=begin;
  610.     if(rv(root)){
  611.       i_cblock_destructor(rc(root));
  612.       rc(root)=NULL;
  613.     }
  614.     {
  615.       size16 *buff=malloc(fs(v)*sizeof(size16));
  616.       memcpy(buff,fv(v),fs(v)*sizeof(size16));
  617.       root->vector=c_alloc(buff,fb(v),fs(v));
  618.     }    
  619.     return(1);
  620.   }else
  621.     return(0);
  622. }
  623. static int vsort(const void *a,const void *b){
  624.   return((*(v_fragment **)a)->begin-(*(v_fragment **)b)->begin);
  625. }
  626. static int i_stage2(cdrom_paranoia *p,long beginword,long endword,
  627.   void(*callback)(long,int)){
  628.   int flag=1,multi=0,ret=0;
  629.   root_block *root=&(p->root);
  630. #ifdef NOISY
  631.   fprintf(stderr,"Fragments:%ldn",p->fragments->active);
  632.   fflush(stderr);
  633. #endif
  634.   while(flag){
  635.     /* loop through all the current fragments */
  636.     v_fragment *first=v_first(p);
  637.     long active=p->fragments->active,count=0;
  638.     v_fragment *list[active];
  639.     while(first){
  640.       v_fragment *next=v_next(first);
  641.       list[count++]=first;
  642.       first=next;
  643.     }
  644.     flag=0;
  645.     if(count){
  646.       qsort(list,active,sizeof(v_fragment *),&vsort);
  647.       
  648.       for(count=0;count<active;count++){
  649. first=list[count];
  650. if(first->one){
  651.   if(rv(root)==NULL){
  652.     if(i_init_root(&(p->root),first,beginword,callback)){
  653.       free_v_fragment(first);
  654.       flag=1;
  655.       ret++;
  656.     }
  657.   }else{
  658.     if(i_stage2_each(root,first,1,multi,callback)){
  659.       ret++;
  660.       flag=1;
  661.       multi=0;
  662.     }
  663.   }
  664. }
  665.       }
  666.     }
  667.     if(!flag){
  668.       if(!multi){
  669. multi=1;
  670. flag=1;
  671.       }
  672.     }else{
  673.       multi=0;
  674.     }
  675.   }
  676.   return(ret);
  677. }
  678. static void i_end_case(cdrom_paranoia *p,long endword,
  679.     void(*callback)(long,int)){
  680.   root_block *root=&p->root;
  681.   /* have an 'end' flag; if we've just read in the last sector in a
  682.      session, set the flag.  If we verify to the end of a fragment
  683.      which has the end flag set, we're done (set a done flag).  Pad
  684.      zeroes to the end of the read */
  685.   
  686.   if(root->lastsector==0)return;
  687.   if(endword<re(root))return;
  688.   
  689.   {
  690.     long addto=endword-re(root);
  691.     char *temp=calloc(addto,sizeof(char)*2);
  692.     c_append(rc(root),(void *)temp,addto);
  693.     free(temp);
  694.     /* trash da cache */
  695.     paranoia_resetcache(p);
  696.   }
  697. }
  698. /* We want to add a sector. Look through the caches for something that
  699.    spans.  Also look at the flags on the c_block... if this is an
  700.    obliterated sector, get a bit of a chunk past the obliteration. */
  701. /* Not terribly smart right now, actually.  We can probably find
  702.    *some* match with a cache block somewhere.  Take it and continue it
  703.    through the skip */
  704. static void verify_skip_case(cdrom_paranoia *p,void(*callback)(long,int)){
  705.   root_block *root=&(p->root);
  706.   c_block *graft=NULL;
  707.   int vflag=0;
  708.   int gend=0;
  709.   long post;
  710.   
  711. #ifdef NOISY
  712. fprintf(stderr,"nskippingn");
  713. #endif
  714.   if(rv(root)==NULL){
  715.     post=0;
  716.   }else{
  717.     post=re(root);
  718.   }
  719.   if(post==-1)post=0;
  720.   (*callback)(post,PARANOIA_CB_SKIP);
  721.   
  722.   /* We want to add a sector.  Look for a c_block that spans,
  723.      preferrably a verified area */
  724.   {
  725.     c_block *c=c_first(p);
  726.     while(c){
  727.       long cbegin=cb(c);
  728.       long cend=ce(c);
  729.       if(cbegin<=post && cend>post){
  730. long vend=post;
  731. if(c->flags[post-cbegin]&4){
  732.   /* verified area! */
  733.   while(vend<cend && (c->flags[vend-cbegin]&4))vend++;
  734.   if(!vflag || vend>vflag){
  735.     graft=c;
  736.     gend=vend;
  737.   }
  738.   vflag=1;
  739. }else{
  740.   /* not a verified area */
  741.   if(!vflag){
  742.     while(vend<cend && (c->flags[vend-cbegin]&4)==0)vend++;
  743.     if(graft==NULL || gend>vend){
  744.       /* smallest unverified area */
  745.       graft=c;
  746.       gend=vend;
  747.     }
  748.   }
  749. }
  750.       }
  751.       c=c_next(c);
  752.     }
  753.     if(graft){
  754.       long cbegin=cb(graft);
  755.       long cend=ce(graft);
  756.       while(gend<cend && (graft->flags[gend-cbegin]&4))gend++;
  757.       gend=min(gend+OVERLAP_ADJ,cend);
  758.       if(rv(root)==NULL){
  759. size16 *buff=malloc(cs(graft));
  760. memcpy(buff,cv(graft),cs(graft));
  761. rc(root)=c_alloc(buff,cb(graft),cs(graft));
  762.       }else{
  763. c_append(rc(root),cv(graft)+post-cbegin,
  764.  gend-post);
  765.       }
  766.       root->returnedlimit=re(root);
  767.       return;
  768.     }
  769.   }
  770.   /* No?  Fine.  Great.  Write in some zeroes :-P */
  771.   {
  772.     void *temp=calloc(CD_FRAMESIZE_RAW,sizeof(size16));
  773.     if(rv(root)==NULL){
  774.       rc(root)=c_alloc(temp,post,CD_FRAMESIZE_RAW);
  775.     }else{
  776.       c_append(rc(root),temp,CD_FRAMESIZE_RAW);
  777.       free(temp);
  778.     }
  779.     root->returnedlimit=re(root);
  780.   }
  781. }    
  782. /**** toplevel ****************************************/
  783. void paranoia_free(cdrom_paranoia *p){
  784.   paranoia_resetall(p);
  785.   free(p);
  786. }
  787. void paranoia_modeset(cdrom_paranoia *p,int enable){
  788.   p->enable=enable;
  789. }
  790. #if 0
  791. long paranoia_seek(cdrom_paranoia *p,long seek,int mode){
  792.   long sector;
  793.   long ret;
  794.   switch(mode){
  795.   case SEEK_SET:
  796.     sector=seek;
  797.     break;
  798.   case SEEK_END:
  799.     sector=cdda_disc_lastsector(p->d)+seek;
  800.     break;
  801.   default:
  802.     sector=p->cursor+seek;
  803.     break;
  804.   }
  805.   
  806.   if(cdda_sector_gettrack(p->d,sector)==-1)return(-1);
  807.   i_cblock_destructor(p->root.vector);
  808.   p->root.vector=NULL;
  809.   p->root.lastsector=0;
  810.   p->root.returnedlimit=0;
  811.   ret=p->cursor;
  812.   p->cursor=sector;
  813.   i_paranoia_firstlast(p);
  814.   
  815.   /* Evil hack to fix pregap patch for NEC drives! To be rooted out in a10 */
  816.   p->current_firstsector=sector;
  817.   return(ret);
  818. }
  819. #endif
  820. /* returns last block read, -1 on error */
  821. c_block *i_read_c_block(cdrom_paranoia *p,long beginword,long endword,
  822.      void(*callback)(long,int)){
  823. /* why do it this way?  We need to read lots of sectors to kludge
  824.    around stupid read ahead buffers on cheap drives, as well as avoid
  825.    expensive back-seeking. We also want to 'jiggle' the start address
  826.    to try to break borderline drives more noticeably (and make broken
  827.    drives with unaddressable sectors behave more often). */
  828.       
  829.   long readat,firstread;
  830.   long totaltoread=p->readahead;
  831.   long sectatonce=p->d->nsectors;
  832.   long driftcomp=(float)p->dyndrift/CD_FRAMEWORDS+.5;
  833.   c_block *new=NULL;
  834.   root_block *root=&p->root;
  835.   size16 *buffer=NULL;
  836.   char *flags=NULL;
  837.   long sofar;
  838.   long dynoverlap=(p->dynoverlap+CD_FRAMEWORDS-1)/CD_FRAMEWORDS; 
  839.   long anyflag=0;
  840.   /* What is the first sector to read?  want some pre-buffer if
  841.      we're not at the extreme beginning of the disc */
  842.   
  843.   if(p->enable&(PARANOIA_MODE_VERIFY|PARANOIA_MODE_OVERLAP)){
  844.     
  845.     /* we want to jitter the read alignment boundary */
  846.     long target;
  847.     if(rv(root)==NULL || rb(root)>beginword)
  848.       target=p->cursor-dynoverlap; 
  849.     else
  850.       target=re(root)/(CD_FRAMEWORDS)-dynoverlap;
  851.     if(target+MIN_SECTOR_BACKUP>p->lastread && target<=p->lastread)
  852.       target=p->lastread-MIN_SECTOR_BACKUP;
  853.       
  854.     /* we want to jitter the read alignment boundary, as some
  855.        drives, beginning from a specific point, will tend to
  856.        lose bytes between sectors in the same place.  Also, as
  857.        our vectors are being made up of multiple reads, we want
  858.        the overlap boundaries to move.... */
  859.     
  860.     readat=(target&(~((long)JIGGLE_MODULO-1)))+p->jitter;
  861.     if(readat>target)readat-=JIGGLE_MODULO;
  862.     p->jitter++;
  863.     if(p->jitter>=JIGGLE_MODULO)p->jitter=0;
  864.      
  865.   }else{
  866.     readat=p->cursor; 
  867.   }
  868.   
  869.   readat+=driftcomp;
  870.   
  871.   if(p->enable&(PARANOIA_MODE_OVERLAP|PARANOIA_MODE_VERIFY)){
  872.     flags=calloc(totaltoread*CD_FRAMEWORDS,1);
  873.     new=new_c_block(p);
  874.     recover_cache(p);
  875.   }else{
  876.     /* in the case of root it's just the buffer */
  877.     paranoia_resetall(p);
  878.     new=new_c_block(p);
  879.   }
  880.   buffer=malloc(totaltoread*CD_FRAMESIZE_RAW);
  881.   sofar=0;
  882.   firstread=-1;
  883.   
  884.   /* actual read loop */
  885.   while(sofar<totaltoread){
  886.     long secread=sectatonce;
  887.     long adjread=readat;
  888.     long thisread;
  889.     /* don't under/overflow the audio session */
  890.     if(adjread<p->current_firstsector){
  891.       secread-=p->current_firstsector-adjread;
  892.       adjread=p->current_firstsector;
  893.     }
  894.     if(adjread+secread-1>p->current_lastsector)
  895.       secread=p->current_lastsector-adjread+1;
  896.     
  897.     if(sofar+secread>totaltoread)secread=totaltoread-sofar;
  898.     
  899.     if(secread>0){
  900.       
  901.       if(firstread<0)firstread=adjread;
  902.       if((thisread=cdda_read(p->d,buffer+sofar*CD_FRAMEWORDS,adjread,
  903.     secread))<secread){
  904. if(thisread<0)thisread=0;
  905. /* Uhhh... right.  Make something up. But don't make us seek
  906.            backward! */
  907. (*callback)((adjread+thisread)*CD_FRAMEWORDS,PARANOIA_CB_READERR);  
  908. memset(buffer+(sofar+thisread)*CD_FRAMEWORDS,0,
  909.        CD_FRAMESIZE_RAW*(secread-thisread));
  910. if(flags)memset(flags+(sofar+thisread)*CD_FRAMEWORDS,2,
  911.        CD_FRAMEWORDS*(secread-thisread));
  912.       }
  913.       if(thisread!=0)anyflag=1;
  914.       
  915.       if(flags && sofar!=0){
  916. /* Don't verify across overlaps that are too close to one
  917.            another */
  918. int i=0;
  919. for(i=-MIN_WORDS_OVERLAP/2;i<MIN_WORDS_OVERLAP/2;i++)
  920.   flags[sofar*CD_FRAMEWORDS+i]|=1;
  921.       }
  922.       p->lastread=adjread+secread;
  923.       
  924.       if(adjread+secread-1==p->current_lastsector)
  925. new->lastsector=-1;
  926.       
  927.       (*callback)((adjread+secread-1)*CD_FRAMEWORDS,PARANOIA_CB_READ);
  928.       
  929.       sofar+=secread;
  930.       readat=adjread+secread; 
  931.     }else
  932.       if(readat<p->current_firstsector)
  933. readat+=sectatonce; /* due to being before the readable area */
  934.       else
  935. break; /* due to being past the readable area */
  936.   }
  937.   if(anyflag){
  938.     new->vector=buffer;
  939.     new->begin=firstread*CD_FRAMEWORDS-p->dyndrift;
  940.     new->size=sofar*CD_FRAMEWORDS;
  941.     new->flags=flags;
  942.   }else{
  943.     if(new)free_c_block(new);
  944.     free(buffer);
  945.     free(flags);
  946.     new=NULL;
  947.   }
  948.   return(new);
  949. }
  950. /* The returned buffer is *not* to be freed by the caller.  It will
  951.    persist only until the next call to paranoia_read() for this p */
  952. size16 *paranoia_read(cdrom_paranoia *p, void(*callback)(long,int)){
  953.   long beginword=p->cursor*(CD_FRAMEWORDS);
  954.   long endword=beginword+CD_FRAMEWORDS;
  955.   long retry_count=0,lastend=-2;
  956.   root_block *root=&p->root;
  957.   if(beginword>p->root.returnedlimit)p->root.returnedlimit=beginword;
  958.   lastend=re(root);
  959.   
  960.   /* First, is the sector we want already in the root? */
  961.   while(rv(root)==NULL ||
  962. rb(root)>beginword || 
  963. (re(root)<endword+(MAX_SECTOR_OVERLAP*CD_FRAMEWORDS) &&
  964.  p->enable&(PARANOIA_MODE_VERIFY|PARANOIA_MODE_OVERLAP)) ||
  965. re(root)<endword){
  966.     
  967.     /* Nope; we need to build or extend the root verified range */
  968.     
  969.     if(p->enable&(PARANOIA_MODE_VERIFY|PARANOIA_MODE_OVERLAP)){
  970.       i_paranoia_trim(p,beginword,endword);
  971.       recover_cache(p);
  972.       if(rb(root)!=-1 && p->root.lastsector)
  973. i_end_case(p,endword+(MAX_SECTOR_OVERLAP*CD_FRAMEWORDS),
  974. callback);
  975.       else
  976. i_stage2(p,beginword,
  977.       endword+(MAX_SECTOR_OVERLAP*CD_FRAMEWORDS),
  978.       callback);
  979.     }else
  980.       i_end_case(p,endword+(MAX_SECTOR_OVERLAP*CD_FRAMEWORDS),
  981.  callback); /* only trips if we're already done */
  982.     
  983.     if(!(rb(root)==-1 || rb(root)>beginword || 
  984.  re(root)<endword+(MAX_SECTOR_OVERLAP*CD_FRAMEWORDS))) 
  985.       break;
  986.     
  987.     /* Hmm, need more.  Read another block */
  988.     {    
  989.       c_block *new=i_read_c_block(p,beginword,endword,callback);
  990.       
  991.       if(new){
  992. if(p->enable&(PARANOIA_MODE_OVERLAP|PARANOIA_MODE_VERIFY)){
  993.       
  994.   if(p->enable&PARANOIA_MODE_VERIFY)
  995.     i_stage1(p,new,callback);
  996.   else{
  997.     /* just make v_fragments from the boundary information. */
  998.     long begin=0,end=0;
  999.     
  1000.     while(begin<cs(new)){
  1001.       while(end<cs(new)&&(new->flags[begin]&1))begin++;
  1002.       end=begin+1;
  1003.       while(end<cs(new)&&(new->flags[end]&1)==0)end++;
  1004.       {
  1005. new_v_fragment(p,new,begin+cb(new),
  1006.        end+cb(new),
  1007.        (new->lastsector && cb(new)+end==ce(new)));
  1008.       }
  1009.       begin=end;
  1010.     }
  1011.   }
  1012.   
  1013. }else{
  1014.   if(p->root.vector)i_cblock_destructor(p->root.vector);
  1015.   free_elem(new->e,0);
  1016.   p->root.vector=new;
  1017.   i_end_case(p,endword+(MAX_SECTOR_OVERLAP*CD_FRAMEWORDS),
  1018.   callback);
  1019.       
  1020. }
  1021.       }
  1022.     }
  1023.     /* Are we doing lots of retries?  **************************************/
  1024.     
  1025.     /* Check unaddressable sectors first.  There's no backoff here; 
  1026.        jiggle and minimum backseek handle that for us */
  1027.     
  1028.     if(rb(root)!=-1 && lastend+588<re(root)){ /* If we've not grown
  1029.  half a sector */
  1030.       lastend=re(root);
  1031.       retry_count=0;
  1032.     }else{
  1033.       /* increase overlap or bail */
  1034.       retry_count++;
  1035.       
  1036.       /* The better way to do this is to look at how many actual
  1037.  matches we're getting and what kind of gap */
  1038.       if(retry_count%5==0){
  1039. if(p->dynoverlap==MAX_SECTOR_OVERLAP*CD_FRAMEWORDS ||
  1040.    retry_count==20){
  1041.   if(!(p->enable&PARANOIA_MODE_NEVERSKIP))verify_skip_case(p,callback);
  1042.   retry_count=0;
  1043. }else{
  1044.   if(p->stage1.offpoints!=-1){ /* hack */
  1045.     p->dynoverlap*=1.5;
  1046.     if(p->dynoverlap>MAX_SECTOR_OVERLAP*CD_FRAMEWORDS)
  1047.       p->dynoverlap=MAX_SECTOR_OVERLAP*CD_FRAMEWORDS;
  1048.     (*callback)(p->dynoverlap,PARANOIA_CB_OVERLAP);
  1049.   }
  1050. }
  1051.       }
  1052.     }
  1053.   }
  1054.   p->cursor++;
  1055.   return(rv(root)+(beginword-rb(root)));
  1056. }
  1057. /* a temporary hack */
  1058. void paranoia_overlapset(cdrom_paranoia *p, long overlap){
  1059.   p->dynoverlap=overlap*CD_FRAMEWORDS;
  1060.   p->stage1.offpoints=-1; 
  1061. }