home *** CD-ROM | disk | FTP | other *** search
/ PC World 2005 November / PCWorld_2005-11_cd.bin / software / vyzkuste / divfix / DivFix110.exe / Source / DivX.pas < prev    next >
Pascal/Delphi Source File  |  2003-05-05  |  47KB  |  1,549 lines

  1. {DivFix is a utility for reindexing partial DivX AVI movies
  2. Copyright (C) 2000-2003  Csaba Budai
  3.  
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2 of the License, or
  7. (at your option) any later version.
  8.  
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. GNU General Public License for more details.
  13.  
  14. You should have received a copy of the GNU General Public License
  15. along with this program; if not, write to the Free Software
  16. Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA}
  17.  
  18. unit DivX;
  19. {$DEFINE WINDOWS}
  20.  
  21. interface
  22.  
  23. uses
  24.   SysUtils, Classes,
  25. {$IFDEF WINDOWS}
  26.   Windows, Messages, Graphics, Controls, Forms, Dialogs, StdCtrls, Mask, Menus,
  27.   ExtCtrls, Buttons, DropSource, DropTarget,ComCtrls, OleCtnrs, ShellApi, FileCtrl;
  28. {$ELSE}
  29.   QStdCtrls, QForms, QExtCtrls, QControls, QComCtrls, QGraphics, QDialogs, QTypes, Qt,
  30.   QMenus, QMask, QButtons;
  31. {$ENDIF}
  32.  
  33.  
  34. type
  35.   TForm1 = class(TForm)
  36.     Button1: TButton;
  37.     Button2: TButton;
  38.     Button3: TButton;
  39.     Button4: TButton;
  40.     SpeedButton2: TSpeedButton;
  41.     SpeedButton3: TSpeedButton;
  42.     CheckBox1: TCheckBox;
  43.     CheckBox2: TCheckBox;
  44.     CheckBox3: TCheckBox;
  45.     MaskEdit2: TMaskEdit;
  46.     MaskEdit3: TMaskEdit;
  47.     MainMenu1: TMainMenu;
  48.     File1: TMenuItem;
  49.     Open1: TMenuItem;
  50.     Rebuild1: TMenuItem;
  51.     Strip1: TMenuItem;
  52.     Check1: TMenuItem;
  53.     Exit1: TMenuItem;
  54.     Settings1: TMenuItem;
  55.     Stayontop1: TMenuItem;
  56.     Help1: TMenuItem;
  57.     About1: TMenuItem;
  58.     OpenDialog1: TOpenDialog;
  59.     OpenDialog2: TOpenDialog;
  60. {$IFDEF WINDOWS}
  61.     DropFileTarget1: TDropFileTarget;
  62. {$ENDIF}
  63.     ProgressBar1: TProgressBar;
  64.     Image1: TImage;
  65.     Bevel1: TBevel;
  66.     Button5: TButton;
  67.     Button6: TButton;
  68.     ListBox1: TListBox;
  69.     Bevel2: TBevel;
  70.     Button7: TButton;
  71. {$IFDEF WINDOWS}
  72.     RichEdit1: TRichEdit;
  73. {$ELSE}
  74.         Memo1: TMemo;
  75. {$ENDIF}
  76.     PopupMenu1: TPopupMenu;
  77.     Clear1: TMenuItem;
  78.     Autoclear1: TMenuItem;
  79.     Autoclearlist1: TMenuItem;
  80.     procedure SpeedButton2Click(Sender: TObject);
  81.     procedure SpeedButton3Click(Sender: TObject);
  82.     procedure Button1Click(Sender: TObject);
  83.     procedure Button2Click(Sender: TObject);
  84.     procedure Exit1Click(Sender: TObject);
  85.     procedure About1Click(Sender: TObject);
  86.     procedure StayTop(Sender: TObject);
  87.     procedure FormCreate(Sender: TObject);
  88.     procedure FormDestroy(Sender: TObject);
  89. {$IFDEF WINDOWS}
  90.     procedure DropFileTarget1Drop(Sender: TObject; ShiftState: TShiftState;
  91.       Point: TPoint; var Effect: Integer);
  92. {$ENDIF}
  93.     procedure Button3Click(Sender: TObject);
  94.     procedure Button4Click(Sender: TObject);
  95.     procedure CheckBox1Click(Sender: TObject);
  96.     procedure CheckBox3Click(Sender: TObject);
  97.     procedure ShowWebPage(Sender: TObject);
  98.     procedure Button5Click(Sender: TObject);
  99.     procedure Button6Click(Sender: TObject);
  100.     procedure Button7Click(Sender: TObject);
  101.     procedure Clear1Click(Sender: TObject);
  102.     procedure FormKeyDown(Sender: TObject; var Key: Word;
  103.       Shift: TShiftState);
  104.     procedure Autoclear1Click(Sender: TObject);
  105.     procedure Autoclearlist1Click(Sender: TObject);
  106.  
  107.   private
  108.     { Private declarations }
  109.   public
  110.       Input,Output                : File;
  111.     Backup                            :    File;
  112.     Log                                    :    Text;
  113.     Config                            :    Text;
  114.         i,j                                    :    Cardinal;
  115.         Size,Position                :    Cardinal;
  116.     Scale,Rate                    :    Cardinal;
  117.         StreamStart                    :    Cardinal;
  118.     IndexStart                    :    Cardinal;
  119.     StreamSize                    :    Cardinal;
  120.     AVISize                            :    Cardinal;
  121.     Difference                    :    Cardinal;
  122.     IndexDifference            :    Cardinal;
  123.     Frame,Time                    :    Cardinal;
  124.         LastIndexPosition        :    Cardinal;
  125.     LastBackupPosition    :    Cardinal;
  126.     LastFrame,LastIndex    :    Cardinal;
  127.     Item                                :    Cardinal;
  128.     Errors                            :    Cardinal;
  129.         FrameType                        :    Cardinal;
  130.     KeyType                            :    Cardinal;
  131.     Interleaved                : Boolean;
  132.     OnTop                                :    Boolean;
  133.     StopButton                    :    Boolean;
  134.     Logging                            :    Boolean;
  135.     CommandLine                    :    Boolean;
  136.     CfgStay                            :    Boolean;
  137.     CfgClear                        :    Boolean;
  138.     CfgCList                        :    Boolean;
  139.     CfgKeep                            :    Boolean;
  140.     CfgCut                            :    Boolean;
  141.     CfgLog                            :    Boolean;
  142.         CfgDir                            :    String;
  143.     CfgDest                            :    String;
  144.     ConfigDir                        :    String;
  145.     Text,Hour,Minute        : String;
  146.     Second                            :    String;
  147.     Text2                                :    String[2];
  148.     Codec                                :    String[4];
  149.         Chunkname                        :    String[8];
  150.         Temp                                : integer;
  151.         Buffer                            :    Array [0..32800] Of Byte;
  152.   end;
  153.  
  154.   Const
  155.       KeyFrame  :    Longint = 16;
  156.     NormFrame    :    Longint = 0;
  157.     Number        :    Set of char =['0'..'9'];
  158.  
  159. var
  160.   Form1: TForm1;
  161.  
  162. implementation
  163.  
  164. uses About, DirRequester;
  165.  
  166. {$IFDEF WINDOWS}
  167. {$R *.DFM}
  168. {$ELSE}
  169. {$R *.dfm}
  170. {$ENDIF}
  171.  
  172. procedure DisableButtons;
  173. begin
  174.     Form1.File1.Enabled:=False;
  175.     Form1.Settings1.Enabled:=False;
  176.     Form1.Help1.Enabled:=False;
  177.     Form1.ListBox1.Enabled:=False;
  178.      Form1.SpeedButton2.Enabled:=False;
  179.      Form1.SpeedButton3.Enabled:=False;
  180.     Form1.MaskEdit2.Enabled:=False;
  181.     Form1.MaskEdit3.Enabled:=False;
  182.     Form1.Button1.Enabled:=False;
  183.   Form1.Button2.Enabled:=False;
  184.   Form1.Button3.Enabled:=False;
  185.     Form1.Button5.Enabled:=False;
  186.   Form1.Button6.Enabled:=False;
  187.   Form1.Button7.Enabled:=False;
  188.   Form1.CheckBox1.Enabled:=False;
  189.   Form1.CheckBox2.Enabled:=False;
  190.   Form1.CheckBox3.Enabled:=False;
  191. end;
  192.  
  193. procedure EnableButtons;
  194. begin
  195.     Form1.File1.Enabled:=True;
  196.     Form1.Settings1.Enabled:=True;
  197.     Form1.Help1.Enabled:=True;
  198.     Form1.ListBox1.Enabled:=True;
  199.     If Form1.CheckBox1.Checked Then
  200.   Begin
  201.       Form1.SpeedButton2.Enabled:=True;
  202.       Form1.MaskEdit2.Enabled:=True;
  203.   End;
  204.     If Form1.CheckBox3.Checked Then
  205.   Begin
  206.       Form1.SpeedButton3.Enabled:=True;
  207.       Form1.MaskEdit3.Enabled:=True;
  208.   End;
  209.      Form1.Button1.Enabled:=True;
  210.   Form1.Button2.Enabled:=True;
  211.   Form1.Button3.Enabled:=True;
  212.      Form1.Button5.Enabled:=True;
  213.   Form1.Button6.Enabled:=True;
  214.   Form1.Button7.Enabled:=True;
  215.   Form1.CheckBox1.Enabled:=True;
  216.   If Form1.CheckBox1.Checked Then Form1.CheckBox2.Enabled:=True;
  217.   Form1.CheckBox3.Enabled:=True;
  218. end;
  219.  
  220. procedure WriteOut(Text : String);
  221. begin
  222.     If Form1.Logging Then Writeln(Form1.Log,Text)
  223.   Else
  224.   Begin
  225. {$IFDEF WINDOWS}
  226.       Form1.RichEdit1.Lines.Append(Text);
  227.     Form1.RichEdit1.Perform(EM_SCROLLCARET,0,0);
  228. {$ELSE}
  229.       Form1.Memo1.Lines.Append(Text);
  230. {$ENDIF}
  231.   End;
  232. end;
  233.  
  234. procedure ZeroAlign(Var Text : String);
  235. Var    i    : Integer;
  236.  
  237. begin
  238.     For i:=1 To Length(Text) Do
  239.       If Text[i]=' ' Then Text[i]:='0';
  240. end;
  241.  
  242. function CheckOtherIndex(Var Input : File) : Cardinal;
  243. Var    Position,i    :    Cardinal;
  244.         OldPosition    :    Cardinal;
  245.     Buffer            :    Array [0..32800] of Byte;
  246.     Text                :    String[2];
  247.     Text2                :    String[4];
  248.     Temp                :    Integer;
  249.  
  250. begin
  251.     OldPosition:=FilePos(Input);
  252.   Seek(Input,FileSize(Input)-32768);
  253.   BlockRead(Input,Buffer,32768);
  254.   Text2:='    ';
  255.   i:=32768;
  256.   Repeat
  257.       Move(Buffer[i],Text2[1],4);
  258.     Text:=Copy(Text2,3,2);
  259.       Dec(i);
  260.   Until (i<0) Or (((Text='dc') Or (Text='db') Or (Text='wb')) And ((Text2[1] In Number) And
  261.               (Text2[2] In Number))) Or (Text2='idx1');
  262.   If (((Text='dc') Or (Text='db') Or (Text='wb')) And ((Text2[1] In Number) And (Text2[2] In Number))) Then
  263.   Begin
  264.       Move(Buffer[i-15],Text2[1],4);
  265.     Text:=Copy(Text2,3,2);
  266.     If (((Text='dc') Or (Text='db') Or (Text='wb')) And ((Text2[1] In Number) And (Text2[2] In Number))) Then
  267.     Begin
  268.           Position:=FileSize(Input);
  269.           i:=32768;
  270.           If Position>32768 Then
  271.           Repeat
  272.                 Dec(Position,32764);
  273.             Seek(Input,Position);
  274.             BlockRead(Input,Buffer,32768,Temp);
  275.             i:=Temp;
  276.             Repeat
  277.                     Dec(i);
  278.               Move(Buffer[i],Text2[1],4);
  279.             Until (i<0) Or (Text2='idx1');
  280.             Until (Position<32768) Or (Text2='idx1');
  281.           If (Position<32768) And (Text2<>'idx1') Then
  282.           Begin
  283.               i:=Position;
  284.             Position:=0;
  285.             Seek(Input,0);
  286.             Repeat
  287.                     Dec(i);
  288.               Move(Buffer[i],Text2[1],4);
  289.             Until (i<0) Or (Text2='idx1');
  290.           End;
  291.           Seek(Input,OldPosition);
  292.           If Text2='idx1' Then Result:=Position+i
  293.           Else Result:=0;
  294.     End
  295.     Else Result:=0;
  296.   End
  297.   Else Result:=0;
  298. end;
  299.  
  300. procedure TForm1.SpeedButton2Click(Sender: TObject);
  301. begin
  302.     Form4.Left:=Form1.Left+70;
  303.   Form4.Top:=Form1.Top-28;
  304.   Form1.Enabled:=False;
  305. {$IFDEF WINDOWS}
  306.   Application.NormalizeTopMosts;
  307.     Form4.ShowModal;
  308.   Application.RestoreTopMosts;
  309.     If Stayontop1.Checked Then
  310.     SetWindowPos(TForm1(Self).Handle,HWND_TOPMOST,0,0,0,0,SWP_NOSIZE+SWP_NOMOVE);
  311. {$ELSE}
  312.     Form4.ShowModal;
  313. {$ENDIF}
  314. end;
  315.  
  316. procedure TForm1.SpeedButton3Click(Sender: TObject);
  317. begin
  318.     If OpenDialog2.Execute Then MaskEdit3.Text:=OpenDialog2.FileName;
  319. end;
  320.  
  321. procedure TForm1.Button1Click(Sender: TObject);
  322. Var k    :    Cardinal;
  323.  
  324. Label BError;
  325. Label BStartRead;
  326.  
  327. begin
  328. {$IFDEF WINDOWS}
  329.     If Autoclear1.Checked Then RichEdit1.Clear;
  330. {$ELSE}
  331.     If Autoclear1.Checked Then Memo1.Clear;
  332. {$ENDIF}
  333.     Logging:=False;
  334.     DisableButtons;
  335.     If ListBox1.Items.Count=0 Then
  336.   Begin
  337.         WriteOut(' No file selected.');
  338.     EnableButtons;
  339.       Exit;
  340.   End
  341.   Else
  342.   Begin
  343.        i:=0;
  344.       While i<=ListBox1.Items.Count-1 Do
  345.     Begin
  346. {$IFDEF WINDOWS}
  347.             ListBox1.Perform(LB_SETSEL,0,i);
  348. {$ENDIF}
  349.       Inc(i);
  350.     End;
  351.   End;
  352.   Item:=0;
  353.   Errors:=0;
  354.     If CheckBox3.Checked Then WriteOut(' Rebuilding index...');
  355.   Repeat
  356. {$IFDEF WINDOWS}
  357.          If Item>0 Then ListBox1.Perform(LB_SETSEL,0,Item-1);
  358.       ListBox1.Perform(LB_SETSEL,1,Item);
  359. {$ENDIF}
  360.         AssignFile(Input,ListBox1.Items.Strings[Item]);
  361.         ChDir(ConfigDir);
  362.         AssignFile(Output,'$TEMP.IDX');
  363.       AssignFile(Log,MaskEdit3.Text);
  364.         If CheckBox1.Checked Then
  365.       Begin
  366.           {$I-}
  367.           FileMode:=0;
  368.             Reset(Input,1);
  369.           FileMode:=2;
  370.             {$I+}
  371.       End
  372.       Else
  373.       Begin
  374.              {$I-}
  375.           Reset(Input,1);
  376.           {$I+}
  377.       End;
  378.       If IOResult<>0 Then
  379.         Begin
  380.             WriteOut(' Can not open the file.');
  381.             EnableButtons;
  382.         Exit;
  383.       End;
  384.       Seek(Input,4);
  385.     BlockRead(Input,AVISize,4);
  386.       BlockRead(Input,ChunkName[1],8);
  387.       ChunkName[0]:=#8;
  388.       If ChunkName<>'AVI LIST' Then
  389.       Begin
  390.           WriteOut(' This is not an AVI file.');
  391.         CloseFile(Input);
  392.         EnableButtons;
  393.         Exit;
  394.       End;
  395.         {$I-}
  396.         Rewrite(Output,1);
  397.         {$I+}
  398.         If IOResult<>0 Then
  399.         Begin
  400.             WriteOut(' Cannot create temporary index file.');
  401.         CloseFile(Input);
  402.         EnableButtons;
  403.         Exit;
  404.       End;
  405.         If CheckBox3.Checked Then
  406.       Begin
  407.             {$I-}
  408.             Reset(Log);
  409.             {$I+}
  410.             If IOResult<>0 Then
  411.         Begin
  412.                 {$I-}
  413.                 Rewrite(Log);
  414.                 {$I+}
  415.                 If IOResult<>0 Then
  416.             Begin
  417.                     WriteOut(' Cannot create log file.');
  418.                 CloseFile(Input);
  419.                  CloseFile(Output);
  420.                 EnableButtons;
  421.                 Exit;
  422.               End
  423.           Else
  424.             Begin
  425.                     CloseFile(Log);
  426.                  Append(Log);
  427.             End;
  428.         End
  429.            Else
  430.         Begin
  431.                 CloseFile(Log);
  432.              Append(Log);
  433.         End;
  434.       End;
  435.         If CheckBox1.Checked Then
  436.       Begin
  437.         If (MaskEdit2.Text='') Or (MaskEdit2.Text='./') Or (MaskEdit2.Text='.\') Then
  438.       AssignFile(Backup,ExtractFilePath(ListBox1.Items.Strings[Item])+'DivFix.'+
  439.                            ExtractFileName(ListBox1.Items.Strings[Item]))
  440.       Else
  441.       AssignFile(Backup,ExtractFilePath(MaskEdit2.Text)+'DivFix.'+
  442.                            ExtractFileName(ListBox1.Items.Strings[Item]));
  443.             {$I-}
  444.             Rewrite(Backup,1);
  445.             {$I+}
  446.             If IOResult<>0 Then
  447.             Begin
  448.                 WriteOut(' Cannot create backup file.');
  449.             CloseFile(Input);
  450.             CloseFile(Output);
  451.                 If CheckBox3.Checked Then CloseFile(Log);
  452.             Erase(Output);
  453.             EnableButtons;
  454.             Exit;
  455.           End;
  456.       End;
  457.         If CheckBox3.Checked Then
  458.       Begin
  459.           Logging:=True;
  460.             WriteOut(' Index rebuilding for file: '+ListBox1.Items.Strings[Item]);
  461.       End
  462.       Else WriteOut(' Index rebuilding for file: '+ListBox1.Items.Strings[Item]);
  463.          Chunkname[0]:=#4;
  464.     Codec[0]:=#4;
  465.         Seek(Input,112);
  466.     BlockRead(Input,Codec[1],4);
  467.     Codec:=UpperCase(Codec);
  468.     Seek(Input,128);
  469.     BlockRead(Input,Scale,4);
  470.     BlockRead(Input,Rate,4);
  471.          Position:=16;
  472.       Size:=0;
  473.       Repeat
  474.              Position:=Position+Size;
  475.           Seek(Input,Position);
  476.         BlockRead(Input,Size,4);
  477.            BlockRead(Input,Chunkname[1],4);
  478.            Inc(Position,8);
  479.       Until Chunkname='movi';
  480.          StreamStart:=Position-4;
  481.       StreamSize:=Size;
  482.         IndexStart:=CheckOtherIndex(Input);
  483.       If IndexStart=0 Then IndexStart:=FileSize(Input);
  484.          Chunkname:='idx1';
  485.       BlockWrite(Output,Chunkname[1],4);
  486.          BlockWrite(Output,Size,4);
  487.          LastIndexPosition:=FilePos(Output);
  488.       Position:=4;
  489.          i:=0;
  490.       Frame:=0;
  491.       Difference:=0;
  492.     IndexDifference:=0;
  493.       Interleaved:=False;
  494.       StopButton:=False;
  495.       Seek(Input,0);
  496.       If CheckBox1.Checked Then
  497.       Begin
  498.              For k:=1 To (StreamStart+4) Div 32768 Do
  499.             Begin
  500.                 BlockRead(Input,Buffer,32768,Temp);
  501.                 BlockWrite(Backup,Buffer,Temp);
  502.             End;
  503.             BlockRead(Input,Buffer,((StreamStart+4) Mod 32768),Temp);
  504.             BlockWrite(Backup,Buffer,Temp);
  505.       End;
  506.       Repeat
  507.         ProgressBar1.Position:=Position Div ((FileSize(Input)-StreamStart) Div 100);
  508.         If StreamStart+Position>IndexStart Then Seek(Input,IndexStart)
  509.              Else Seek(Input,StreamStart+Position);
  510.             BStartRead:
  511.            If Not Eof(Input) Then
  512.         Begin
  513.               BlockRead(Input,Chunkname[1],4,Temp);
  514.           If ChunkName='LIST' Then
  515.           Begin
  516.               Seek(Input,FilePos(Input)+8);
  517.             Inc(Position,12);
  518.             Goto BStartRead;
  519.                 End;
  520.           If ChunkName='JUNK' Then
  521.           Begin
  522.               BlockRead(Input,Size,4);
  523.             Position:=Position+Size+8;
  524.           Inc(Difference,(Size+8));
  525.           If StreamStart+Position>IndexStart Then Seek(Input,IndexStart)
  526.               Else Seek(Input,StreamStart+Position);
  527.                     Goto BStartRead;
  528.                 End;
  529.           Text2:=Copy(ChunkName,3,2);
  530.           If (Copy(ChunkName,1,2)='ix') Or (Text2='ix') Then
  531.           Begin
  532.             Inc(Position,16);
  533.           If StreamStart+Position>IndexStart Then Seek(Input,IndexStart)
  534.               Else Seek(Input,StreamStart+Position);
  535.             Interleaved:=True;
  536.             Goto BStartRead;
  537.                 End;
  538.           If Not Eof(Input) Then
  539.           Begin
  540.               If ((ChunkName[1] In Number) And (ChunkName[2] In Number)) And
  541.                ((Text2='dc') Or (Text2='db') Or (Text2='wb')) Then
  542.             Begin
  543.                 If (Text2='dc') Or (Text2='db') Then
  544.             Begin
  545.                 If Frame=0 Then
  546.               Begin
  547.                   BlockRead(Input,Size,4);
  548.                    BlockRead(Input,KeyType,4);
  549.                 If KeyType=65536 Then KeyType:=1
  550.                 Else If KeyType=$b0010000 Then KeyType:=2
  551. //                Else If Codec='DIVX' Then KeyType:=1
  552.                     Else KeyType:=3;
  553.                 Seek(Input,FilePos(Input)-8);
  554.               End;
  555.                 Inc(Frame);
  556.             End;
  557.               If Interleaved Then
  558.               Begin
  559.                   Seek(Input,FilePos(Input)-16);
  560.                 Dec(Position,16);
  561.                 Interleaved:=False;
  562.               End;
  563.                       BlockRead(Input,Size,4,Temp);
  564.               If (Size<0) And (Temp=4) Then
  565.               Begin
  566.                   Inc(Position,4);
  567.                   If StreamStart+Position>IndexStart Then Seek(Input,IndexStart)
  568.                       Else Seek(Input,StreamStart+Position);
  569.                 BlockRead(Input,Chunkname[1],4,Temp);
  570.                 If ChunkName='LIST' Then
  571.                       Begin
  572.                           Seek(Input,FilePos(Input)+8);
  573.                   Inc(Position,12);
  574.                                 Goto BStartRead;
  575.                             End;
  576.                 If ChunkName='JUNK' Then
  577.                       Begin
  578.                           BlockRead(Input,Size,4);
  579.                         Position:=Position+Size+8;
  580.                       If StreamStart+Position>IndexStart Then Seek(Input,IndexStart)
  581.                           Else Seek(Input,StreamStart+Position);
  582.                         Goto BStartRead;
  583.                             End;
  584.                   If StreamStart+Position>IndexStart Then Seek(Input,IndexStart)
  585.                       Else Seek(Input,StreamStart+Position);
  586.                 Goto BError;
  587.                         End;
  588.                   If Not Eof(Input) Then
  589.                   Begin
  590.                           If Size>0 Then BlockRead(Input,FrameType,4)
  591.               Else FrameType:=64;
  592.                       j:=(((Position+Size) Div 2)+((Position+Size) Mod 2))*2+8;
  593.               If StreamStart+j-1>IndexStart Then Seek(Input,IndexStart)
  594.               Else Seek(Input,StreamStart+j-1);
  595.                          If Not Eof(Input) Then
  596.                       Begin
  597.                   If ((Text2='dc') Or (Text2='db')) And (((KeyType=1) And (FrameType=65536))
  598.                 Or ((KeyType=2) And (FrameType=$b0010000))
  599.                 Or ((KeyType=3) And (FrameType And 64=0))) Then
  600.                     If Size>0 Then LastIndexPosition:=FilePos(Output);
  601.                 LastIndex:=FilePos(Output);
  602.                               BlockWrite(Output,Chunkname[1],4);
  603.                   Text2:=Copy(ChunkName,3,2);
  604.                               If ((Text2='dc') Or (Text2='db') Or (Text2='wb')) And
  605.                        ((Chunkname[1]In Number) And (ChunkName[2] In Number)) Then
  606.                     If ((Text2='wb') Or (((KeyType=1) And (FrameType=65536))
  607.                   Or ((KeyType=2) And (FrameType=$b0010000))
  608.                   Or ((KeyType=3) And (FrameType And 64=0)))) And (Size>0) Then
  609.                      BlockWrite(Output,KeyFrame,4)
  610.                                   Else BlockWrite(Output,NormFrame,4);
  611.                               If CheckBox2.Checked Then
  612.                   Begin
  613.                       j:=Position-Difference;
  614.                       BlockWrite(Output,j,4);
  615.                   End
  616.                   Else BlockWrite(Output,Position,4);
  617.                               BlockWrite(Output,Size,4);
  618.                   j:=Position;
  619.                                Position:=(((Position+Size) Div 2)+((Position+Size) Mod 2))*2+8;
  620.                       If StreamStart+j>IndexStart Then Seek(Input,IndexStart)
  621.                           Else Seek(Input,StreamStart+j);
  622.                   If CheckBox1.Checked Then
  623.                   Begin
  624.                     If ((Text2='dc') Or (Text2='db')) And (((KeyType=1) And (FrameType=65536))
  625.                   Or ((KeyType=2) And (FrameType=$b0010000))
  626.                   Or ((KeyType=3) And (FrameType And 64=0))) Then
  627.                       If Size>0 Then LastBackupPosition:=FilePos(Backup);
  628.                   LastFrame:=FilePos(Backup);
  629.                       If Position-j>32768 Then
  630.                       Begin
  631.                           For k:=1 To (Position-j) Div 32768 Do
  632.                         Begin
  633.                                             BlockRead(Input,Buffer,32768,Temp);
  634.                               BlockWrite(Backup,Buffer,Temp);
  635.                           End;
  636.                         BlockRead(Input,Buffer,((Position-j) Mod 32768),Temp);
  637.                              BlockWrite(Backup,Buffer,Temp);
  638.                       End
  639.                       Else
  640.                       Begin
  641.                           BlockRead(Input,Buffer,Position-j,Temp);
  642.                           BlockWrite(Backup,Buffer,Temp);
  643.                       End;
  644.                   End;
  645.                             Inc(i);
  646.                          End;
  647.                        End;
  648.             End
  649.             Else
  650.             Begin
  651.                 BError:
  652.               If Chunkname<>'idx1' Then
  653.               Begin
  654.                 Inc(Errors);
  655.                   Str(Frame,Text);
  656.               Time:=(Frame*Scale) Div Rate;
  657.               Str(Time Div 3600:2,Hour);
  658.               Str(Time Div 60:2,Minute);
  659.               Str(Time Mod 60:2,Second);
  660.                             ZeroAlign(Hour);
  661.                             ZeroAlign(Minute);
  662.                             ZeroAlign(Second);
  663.                     Text:=' Corrupted data detected at frame '+Text+' ('+Hour+':'+Minute
  664.                                 +':'+Second+')';
  665.                   If FilePos(Output)>16 Then Seek(Output,FilePos(Output)-16);
  666.                             WriteOut(Text);
  667.                 Str(StreamStart+Position,Text);
  668.                 Text:=' Error offset: '+Text+' ($'+IntToHex(StreamStart+Position,8)+')';
  669.                 WriteOut(Text);
  670.               IndexDifference:=(FilePos(Output)-LastIndexPosition) Div 16;
  671.               Dec(i,IndexDifference+1);
  672.                 Seek(Output,LastIndexPosition);
  673.                 If CheckBox1.Checked Then
  674.                   If LastBackupPosition>0 Then
  675.                 Begin
  676.                     Seek(Backup,LastBackupPosition);
  677.                 End;
  678.                 j:=Position;
  679.                   Repeat
  680.                       If StreamStart+Position>IndexStart Then Seek(Input,IndexStart)
  681.                           Else Seek(Input,StreamStart+Position);
  682.                     If Not Eof(Input) Then
  683.                     Begin
  684.                             BlockRead(Input,Buffer[1],32768,Temp);
  685.                     k:=1;
  686.                       Repeat
  687.                               If ((Chr(Buffer[k])='d') Or (Chr(Buffer[k])='w')) Then
  688.                             Begin
  689.                                    If ((Chr(Buffer[k+1])='c') Or (Chr(Buffer[k+1])='b')) Then
  690.                              Begin
  691.                                       If StreamStart+Position+k-3>IndexStart Then Seek(Input,IndexStart)
  692.                                           Else Seek(Input,StreamStart+Position+k-3);
  693.                                  If Not Eof(Input) Then BlockRead(Input,ChunkName[1],4);
  694.                                  If Not Eof(Input) Then BlockRead(Input,Size,4);
  695.                                  If Not Eof(Input) Then BlockRead(Input,FrameType,4);
  696.                                End;
  697.                              End;
  698.                             Inc(k);
  699.                       Text2:=Copy(ChunkName,3,2);
  700.                                     Until (((Text2='dc') Or (Text2='db')) And ((ChunkName[1] In Number) And
  701.                               (ChunkName[2] In Number)) And (((KeyType=1) And (FrameType=65536))
  702.                         Or ((KeyType=2) And (FrameType=$b0010000))
  703.                         Or ((KeyType=3) And (FrameType And 64=0))))
  704.                         Or (Chunkname='idx1') Or (k>Temp);
  705.                     Inc(Position,k-3);
  706.                       End;
  707.                               Application.ProcessMessages;
  708.                               If StopButton Then
  709.                               Begin
  710.                                   WriteOut(' Index rebuilding aborted...');
  711.                                 ProgressBar1.Position:=0;
  712.                                 StopButton:=False;
  713.                                     CloseFile(Input);
  714.                                     CloseFile(Output);
  715.                     If CheckBox1.Checked Then CloseFile(Backup);
  716.                     If CheckBox3.Checked Then CloseFile(Log);
  717.                                      Erase(Output);
  718.                     EnableButtons;
  719.                                    Exit;
  720.                               End;
  721.                   Text2:=Copy(ChunkName,3,2);
  722.                   Until (((Text2='dc') Or (Text2='db') Or (Text2='wb')) And
  723.                           ((ChunkName[1] In Number) And (ChunkName[2] In Number))
  724.                     And (((KeyType=1) And (FrameType=65536))
  725.                     Or ((KeyType=2) And (FrameType=$b0010000))
  726.                     Or ((KeyType=3) And (FrameType And 64=0))))
  727.                     Or (Chunkname='idx1') Or Eof(Input);
  728.                      If Not Eof(Input) Then Dec(Position)
  729.               Else
  730.               Begin
  731.                   If CheckBox1.Checked Then
  732.                 Begin
  733.                       Seek(Backup,LastFrame);
  734.                     Truncate(Backup);
  735.                 End;
  736.                 Seek(Output,LastIndex);
  737.                 Truncate(Output);
  738.                 Inc(i,IndexDifference-2);
  739.               End;
  740.                             If CheckBox1.Checked Then
  741.                 Begin
  742.                     If Not(CheckBox2.Checked) Then
  743.                   Begin
  744.                     If StreamStart+j>IndexStart Then Seek(Input,IndexStart)
  745.                               Else Seek(Input,StreamStart+j);
  746.                         If Position-j>32768 Then
  747.                         Begin
  748.                           For k:=1 To (Position-j) Div 32768 Do
  749.                            Begin
  750.                                             BlockRead(Input,Buffer,32768,Temp);
  751.                               BlockWrite(Backup,Buffer,Temp);
  752.                              End;
  753.                            BlockRead(Input,Buffer,((Position-j) Mod 32768),Temp);
  754.                                 BlockWrite(Backup,Buffer,Temp);
  755.                       End
  756.                         Else
  757.                         Begin
  758.                             BlockRead(Input,Buffer,Position-j,Temp);
  759.                             BlockWrite(Backup,Buffer,Temp);
  760.                         End;
  761.                   End
  762.                   Else
  763.                 Difference:=FilePos(Input)-LastBackupPosition-12;
  764.                 End;
  765.               End
  766.               Else
  767.               Begin
  768.                   Seek(Input,FilePos(Input)+6);
  769.                 ChunkName[0]:=#2;
  770.                 BlockRead(Input,ChunkName[1],2);
  771.                 Seek(Input,FilePos(Input)-8);
  772.                 If (ChunkName='dc') Or (ChunkName='wb') Or (ChunkName='db') Then
  773.                 Begin
  774.                     ChunkName[0]:=#4;
  775.                   ChunkName:='idx1';
  776.                 End
  777.                 Else
  778.                 Begin
  779.                     ChunkName[0]:=#4;
  780.                   ChunkName:='0000';
  781.                   Goto BError;
  782.                 End;
  783.               End;
  784.                End;
  785.           End;
  786.         End;
  787.         Application.ProcessMessages;
  788.         If StopButton Then
  789.         Begin
  790.             WriteOut(' Index rebuilding aborted...');
  791.           ProgressBar1.Position:=0;
  792.           StopButton:=False;
  793.               CloseFile(Input);
  794.                  CloseFile(Output);
  795.           If CheckBox1.Checked Then CloseFile(Backup);
  796.           If CheckBox3.Checked Then CloseFile(Log);
  797.               Erase(Output);
  798.           EnableButtons;
  799.             Exit;
  800.         End;
  801.         Until (Eof(Input)) Or (ChunkName='idx1');
  802.          Size:=i*16;
  803.       Seek(Output,4);
  804.          BlockWrite(Output,Size,4);
  805.         If CheckBox1.Checked Then
  806.       Begin
  807.           If ChunkName='idx1' Then StreamSize:=FilePos(Backup)-StreamStart-4
  808.         Else StreamSize:=Filesize(Backup)-StreamStart-4;
  809.           Seek(Backup,StreamStart-4);
  810.       Inc(StreamSize,4);
  811.              BlockWrite(Backup,StreamSize,4);
  812.           Seek(Backup,StreamStart+StreamSize);
  813.         If (StreamStart+StreamSize) MOD 2=1 Then
  814.         Begin
  815.             Buffer[0]:=0;
  816.             BlockWrite(Backup,Buffer,1);
  817.         End;
  818.              Seek(Output,0);
  819.           Repeat
  820.                  BlockRead(Output,Buffer,32768,Temp);
  821.                BlockWrite(Backup,Buffer,Temp);
  822.             Until Not(Temp=32768);
  823.       Str(Errors,Text);
  824.       WriteOut(' Finished with '+ListBox1.Items.Strings[Item]+' .');
  825.             WriteOut(' Number of errors: '+Text);
  826.             WriteOut(' Done.');
  827.       WriteOut('');
  828.         ProgressBar1.Position:=100;
  829.           Truncate(Backup);
  830.           CloseFile(Input);
  831.              CloseFile(Output);
  832.         CloseFile(Backup);
  833.             If CheckBox3.Checked Then CloseFile(Log);
  834.           Erase(Output);
  835.       End
  836.       Else
  837.       Begin
  838.           If ChunkName='idx1' Then StreamSize:=FilePos(Input)-StreamStart-4
  839.         Else StreamSize:=Filesize(Input)-StreamStart;
  840.       Seek(Input,StreamStart-4);
  841.              BlockWrite(Input,StreamSize,4);
  842.       If StreamStart+StreamSize>IndexStart Then Seek(Input,IndexStart)
  843.       Else Seek(Input,StreamStart+StreamSize);
  844.         If (StreamStart+StreamSize) MOD 2=1 Then
  845.         Begin
  846.             Buffer[0]:=0;
  847.             BlockWrite(Input,Buffer,1);
  848.         End;
  849.              Seek(Output,0);
  850.           Repeat
  851.                  BlockRead(Output,Buffer,32768,Temp);
  852.                BlockWrite(Input,Buffer,Temp);
  853.             Until Not(Temp=32768);
  854.           Truncate(Input);
  855.       Str(Errors,Text);
  856.       WriteOut(' Finished with '+ListBox1.Items.Strings[Item]+' .');
  857.             WriteOut(' Number of errors: '+Text);
  858.             WriteOut(' Done.');
  859.           WriteOut('');
  860.             If CheckBox3.Checked Then CloseFile(Log);
  861.         ProgressBar1.Position:=100;
  862.           CloseFile(Input);
  863.              CloseFile(Output);
  864.           Erase(Output);
  865.       End;
  866.     Inc(Item);
  867.   Until Item=ListBox1.Items.Count;
  868.     If CheckBox3.Checked Then
  869.   Begin
  870.       Logging:=False;
  871.         WriteOut(' Done.');
  872.         WriteOut('');
  873.   End;
  874.     If Autoclearlist1.Checked Then ListBox1.Items.Clear;
  875. {$IFDEF WINDOWS}
  876.     ListBox1.Perform(LB_SETSEL,0,Item-1);
  877. {$ENDIF}
  878.   EnableButtons;
  879. end;
  880.  
  881. procedure TForm1.Button2Click(Sender: TObject);
  882. begin
  883. {$IFDEF WINDOWS}
  884.     If Autoclear1.Checked Then RichEdit1.Clear;
  885. {$ELSE}
  886.     If Autoclear1.Checked Then Memo1.Clear;
  887. {$ENDIF}
  888.     DisableButtons;
  889.   If ListBox1.Items.Count=0 Then
  890.   Begin
  891.         WriteOut(' No file selected.');
  892.     EnableButtons;
  893.       Exit;
  894.   End;
  895.     Item:=0;
  896.     If CheckBox3.Checked Then WriteOut(' Stripping index...');
  897.   Repeat
  898.         AssignFile(Input,ListBox1.Items.Strings[Item]);
  899.     AssignFile(Log,MaskEdit3.Text);
  900.       {$I-}
  901.         Reset(Input,1);
  902.         {$I+}
  903.       If IOResult<>0 Then
  904.         Begin
  905.             WriteOut(' Can not open the file.');
  906.         EnableButtons;
  907.         Exit;
  908.       End;
  909.         If CheckBox3.Checked Then
  910.       Begin
  911.             {$I-}
  912.             Reset(Log);
  913.             {$I+}
  914.             If IOResult<>0 Then
  915.         Begin
  916.                 {$I-}
  917.                 Rewrite(Log);
  918.                 {$I+}
  919.         i:=ioresult;
  920.                 If {IOResult}i<>0 Then
  921.             Begin
  922.                     WriteOut(' Cannot create log file.');
  923.                 CloseFile(Input);
  924.                 EnableButtons;
  925.                    Exit;
  926.               End
  927.           Else
  928.                Begin
  929.                     CloseFile(Log);
  930.                    Append(Log);
  931.             End;
  932.            End
  933.              Else
  934.         Begin
  935.                 CloseFile(Log);
  936.                 Append(Log);
  937.           End;
  938.     End;
  939.       Seek(Input,8);
  940.       BlockRead(Input,ChunkName[1],8);
  941.       ChunkName[0]:=#8;
  942.       If ChunkName<>'AVI LIST' Then
  943.       Begin
  944.             WriteOut(' This is not an AVI file.');
  945.         CloseFile(Input);
  946.         EnableButtons;
  947.         Exit;
  948.       End;
  949.         If CheckBox3.Checked Then
  950.       Begin
  951.           Logging:=True;
  952.             WriteOut(' Stripping index for file: '+ListBox1.Items.Strings[Item]);
  953.       End
  954.       Else WriteOut(' Stripping index for file: '+ListBox1.Items.Strings[Item]);
  955.          Position:=16;
  956.       Size:=0;
  957.          Chunkname[0]:=#4;
  958.       Repeat
  959.              Position:=Position+Size;
  960.           Seek(Input,Position);
  961.         BlockRead(Input,Size,4);
  962.            BlockRead(Input,Chunkname[1],4);
  963.            Inc(Position,8);
  964.       Until Chunkname='movi';
  965.          StreamStart:=Position-4;
  966.       StreamSize:=Size;
  967.         IndexStart:=CheckOtherIndex(Input);
  968.     If IndexStart=0 Then
  969.     Begin
  970.           WriteOut(' Unexpected end of file, index not found.');
  971.         CloseFile(Input);
  972.         If CheckBox3.Checked Then CloseFile(Log);
  973.         EnableButtons;
  974.         Exit;
  975.         End;
  976.     Seek(Input,IndexStart);
  977.         Truncate(Input);
  978.       Seek(Input,StreamStart-4);
  979.         BlockWrite(Input,StreamSize,4);
  980.       CloseFile(Input);
  981.         WriteOut(' Done.');
  982.     WriteOut('');
  983.         If CheckBox3.Checked Then CloseFile(Log);
  984.     Inc(Item);
  985.   Until Item=ListBox1.Items.Count;
  986.     If CheckBox3.Checked Then
  987.   Begin
  988.       Logging:=False;
  989.         WriteOut(' Done.');
  990.         WriteOut('');
  991.   End;
  992.     If Autoclearlist1.Checked Then ListBox1.Items.Clear;
  993.     EnableButtons;
  994. end;
  995.  
  996. procedure TForm1.Button3Click(Sender: TObject);
  997. Label CError;
  998. Label CStartRead;
  999.  
  1000. begin
  1001. {$IFDEF WINDOWS}
  1002.     If Autoclear1.Checked Then RichEdit1.Clear;
  1003. {$ELSE}
  1004.     If Autoclear1.Checked Then Memo1.Clear;
  1005. {$ENDIF}
  1006.     DisableButtons;
  1007.     If ListBox1.Items.Count=0 Then
  1008.   Begin
  1009.         WriteOut(' No file selected.');
  1010.     EnableButtons;
  1011.       Exit;
  1012.   End;
  1013.   Item:=0;
  1014.   Errors:=0;
  1015.     If CheckBox3.Checked Then WriteOut(' Error checking... ');
  1016.   Repeat
  1017.         AssignFile(Input,ListBox1.Items.Strings[Item]);
  1018.       AssignFile(Log,MaskEdit3.Text);
  1019.       {$I-}
  1020.       FileMode:=0;
  1021.         Reset(Input,1);
  1022.       FileMode:=2;
  1023.         {$I+}
  1024.       If IOResult<>0 Then
  1025.         Begin
  1026.           WriteOut(' Can not open the file.');
  1027.         EnableButtons;
  1028.         Exit;
  1029.       End;
  1030.         If CheckBox3.Checked Then
  1031.       Begin
  1032.             {$I-}
  1033.             Reset(Log);
  1034.             {$I+}
  1035.             If IOResult<>0 Then
  1036.         Begin
  1037.                 {$I-}
  1038.                 Rewrite(Log);
  1039.                 {$I+}
  1040.                 If IOResult<>0 Then
  1041.             Begin
  1042.                     WriteOut(' Cannot create log file.');
  1043.                 CloseFile(Input);
  1044.                 EnableButtons;
  1045.                 Exit;
  1046.               End
  1047.           Else
  1048.             Begin
  1049.                     CloseFile(Log);
  1050.                  Append(Log);
  1051.             End;
  1052.         End
  1053.            Else
  1054.         Begin
  1055.                 CloseFile(Log);
  1056.              Append(Log);
  1057.         End;
  1058.       End;
  1059.       Seek(Input,8);
  1060.       BlockRead(Input,ChunkName[1],8);
  1061.       ChunkName[0]:=#8;
  1062.       If ChunkName<>'AVI LIST' Then
  1063.       Begin
  1064.           WriteOut(' This is not an AVI file.');
  1065.         CloseFile(Input);
  1066.             If CheckBox3.Checked Then CloseFile(Log);
  1067.         EnableButtons;
  1068.         Exit;
  1069.       End;
  1070.         If CheckBox3.Checked Then
  1071.       Begin
  1072.           Logging:=True;
  1073.             WriteOut(' Error checking for file: '+ListBox1.Items.Strings[Item]);
  1074.       End
  1075.       Else WriteOut(' Error checking for file: '+ListBox1.Items.Strings[Item]);
  1076.       WriteOut(' NOTE: The error checking is not perfect!');
  1077.          Chunkname[0]:=#4;
  1078.     Seek(Input,128);
  1079.     BlockRead(Input,Scale,4);
  1080.     BlockRead(Input,Rate,4);
  1081.          Position:=16;
  1082.       Size:=0;
  1083.       Repeat
  1084.              Position:=Position+Size;
  1085.           Seek(Input,Position);
  1086.         BlockRead(Input,Size,4);
  1087.            BlockRead(Input,Chunkname[1],4);
  1088.            Inc(Position,8);
  1089.       Until Chunkname='movi';
  1090.          StreamStart:=Position-4;
  1091.       StreamSize:=Size;
  1092.         IndexStart:=CheckOtherIndex(Input);
  1093.     If IndexStart=0 Then IndexStart:=FileSize(Input);
  1094.          Chunkname:='idx1';
  1095.       Position:=4;
  1096.          i:=0;
  1097.       Frame:=0;
  1098.       Interleaved:=False;
  1099.       StopButton:=False;
  1100.       Repeat
  1101.         ProgressBar1.Position:=Position Div (FileSize(Input) Div 100);
  1102.       If StreamStart+Position>IndexStart Then Seek(Input,IndexStart)
  1103.            Else Seek(Input,StreamStart+Position);
  1104.            If Not Eof(Input) Then
  1105.         Begin
  1106.             CStartRead:
  1107.               BlockRead(Input,Chunkname[1],4,Temp);
  1108.           If ChunkName='LIST' Then
  1109.           Begin
  1110.               Seek(Input,FilePos(Input)+8);
  1111.             Inc(Position,12);
  1112.             Goto CStartRead;
  1113.                 End;
  1114.           If ChunkName='JUNK' Then
  1115.           Begin
  1116.               BlockRead(Input,Size,4);
  1117.             Position:=Position+Size+8;
  1118.           If StreamStart+Position>IndexStart Then Seek(Input,IndexStart)
  1119.               Else Seek(Input,StreamStart+Position);
  1120.             Goto CStartRead;
  1121.                 End;
  1122.           Text2:=Copy(ChunkName,3,2);
  1123.           If (Copy(ChunkName,1,2)='ix') Or (Text2='ix') Then
  1124.           Begin
  1125.               Seek(Input,FilePos(Input)+12);
  1126.             Inc(Position,16);
  1127.           If StreamStart+Position>IndexStart Then Seek(Input,IndexStart)
  1128.               Else Seek(Input,StreamStart+Position);
  1129.             Interleaved:=True;
  1130.             Goto CStartRead;
  1131.                 End;
  1132.           If Not Eof(Input) Then
  1133.           Begin
  1134.               If ((ChunkName[1] In Number) And (ChunkName[2] In Number)) And
  1135.                ((Text2='dc') Or (Text2='db') Or (Text2='wb')) Then
  1136.             Begin
  1137.                 If (Text2='dc') Or (Text2='db') Then Inc(Frame);
  1138.               If Interleaved Then
  1139.               Begin
  1140.                   Seek(Input,FilePos(Input)-16);
  1141.                 Dec(Position,16);
  1142.                 Interleaved:=False;
  1143.               End;
  1144.                       BlockRead(Input,Size,4,Temp);
  1145.               If (Size<0) And (Temp=4) Then
  1146.               Begin
  1147.                   Inc(Position,4);
  1148.                   If StreamStart+Position>IndexStart Then Seek(Input,IndexStart)
  1149.                       Else Seek(Input,StreamStart+Position);
  1150.                 BlockRead(Input,Chunkname[1],4);
  1151.                       If ChunkName='LIST' Then
  1152.                       Begin
  1153.                           Seek(Input,FilePos(Input)+8);
  1154.                   Inc(Position,12);
  1155.                         Goto CStartRead;
  1156.                             End;
  1157.                 If ChunkName='JUNK' Then
  1158.                       Begin
  1159.                           BlockRead(Input,Size,4);
  1160.                         Position:=Position+Size+8;
  1161.                       If StreamStart+Position>IndexStart Then Seek(Input,IndexStart)
  1162.                           Else Seek(Input,StreamStart+Position);
  1163.                         Goto CStartRead;
  1164.                             End;
  1165.                   If StreamStart+Position>IndexStart Then Seek(Input,IndexStart)
  1166.                       Else Seek(Input,StreamStart+Position);
  1167.                 Goto CError;
  1168.               End;
  1169.                   If Not Eof(Input) Then
  1170.                   Begin
  1171.                       j:=(((Position+Size) Div 2)+((Position+Size) Mod 2))*2+8;
  1172.               If StreamStart+j-1>IndexStart Then Seek(Input,IndexStart)
  1173.                       Else Seek(Input,StreamStart+j-1);
  1174.                          If Not Eof(Input) Then
  1175.                       Begin
  1176.                                Position:=(((Position+Size) Div 2)+((Position+Size) Mod 2))*2+8;
  1177.                             Inc(i);
  1178.                          End;
  1179.                        End;
  1180.             End
  1181.             Else
  1182.                         CError:
  1183.               If Chunkname<>'idx1' Then
  1184.               Begin
  1185.                 Inc(Errors);
  1186.                   Str(Frame,Text);
  1187.               Time:=(Frame*Scale) Div Rate;
  1188.               Str(Time Div 3600:2,Hour);
  1189.               Str(Time Div 60:2,Minute);
  1190.               Str(Time Mod 60:2,Second);
  1191.                             ZeroAlign(Hour);
  1192.                             ZeroAlign(Minute);
  1193.                             ZeroAlign(Second);
  1194.                     Text:=' Corrupted data detected at frame '+Text+' ('+Hour+':'+Minute
  1195.                                 +':'+Second+')';
  1196.                             WriteOut(Text);
  1197.                 Str(StreamStart+Position,Text);
  1198.                 Text:=' Error offset: '+Text+' ($'+IntToHex(StreamStart+Position,8)+')';
  1199.                 WriteOut(Text);
  1200.                   Repeat
  1201.                   If StreamStart+Position>IndexStart Then Seek(Input,IndexStart)
  1202.                           Else Seek(Input,StreamStart+Position);
  1203.                     If Not Eof(Input) Then
  1204.                     Begin
  1205.                             BlockRead(Input,Buffer[1],32768,Temp);
  1206.                     j:=1;
  1207.                       Repeat
  1208.                               If ((Chr(Buffer[j])='d') Or (Chr(Buffer[j])='w')) And (Not Eof(Input)) Then
  1209.                             Begin
  1210.                                   If ((Chr(Buffer[j+1])='c') Or (Chr(Buffer[j+1])='b')) And (Not Eof(Input)) Then
  1211.                              Begin
  1212.                             If StreamStart+Position+j-3>IndexStart Then Seek(Input,IndexStart)
  1213.                                           Else Seek(Input,StreamStart+Position+j-3);
  1214.                                  If Not Eof(Input) Then BlockRead(Input,ChunkName[1],4);
  1215.                                End;
  1216.                              End;
  1217.                             Inc(j);
  1218.                       Text2:=Copy(ChunkName,3,2);
  1219.                                     Until (((Text2='dc') Or (Text2='db') Or
  1220.                               (Text2='wb')) And ((ChunkName[1] In Number) And
  1221.                               (ChunkName[2] In Number))) Or (Chunkname='idx1') Or (j>Temp);
  1222.                       End;
  1223.                   Inc(Position,j-3);
  1224.                   Application.ProcessMessages;
  1225.                             If StopButton Then
  1226.                             Begin
  1227.                                 WriteOut(' Error checking aborted...');
  1228.                               ProgressBar1.Position:=0;
  1229.                               StopButton:=False;
  1230.                     CloseFile(Input);
  1231.                                     If CheckBox3.Checked Then CloseFile(Log);
  1232.                     EnableButtons;
  1233.                                 Exit;
  1234.                             End;
  1235.                   Text2:=Copy(ChunkName,3,2);
  1236.                   Until (((Text2='dc') Or (Text2='db') Or
  1237.                       (Text2='wb')) And ((ChunkName[1] In Number) And
  1238.                       (ChunkName[2] In Number))) Or (Chunkname='idx1') Or Eof(Input);
  1239.                   If Not Eof(Input) Then Dec(Position);
  1240.                 End
  1241.               Else
  1242.               Begin
  1243.                   Seek(Input,FilePos(Input)+6);
  1244.                 ChunkName[0]:=#2;
  1245.                 BlockRead(Input,ChunkName[1],2);
  1246.                 Seek(Input,FilePos(Input)-8);
  1247.                 If (ChunkName='dc') Or (ChunkName='wb') Or (ChunkName='db') Then
  1248.                 Begin
  1249.                     ChunkName[0]:=#4;
  1250.                   ChunkName:='idx1';
  1251.                 End
  1252.                 Else
  1253.                 Begin
  1254.                     ChunkName[0]:=#4;
  1255.                   ChunkName:='0000';
  1256.                   Goto CError;
  1257.                 End
  1258.               End;
  1259.           End;
  1260.         End;
  1261.         Application.ProcessMessages;
  1262.         If StopButton Then
  1263.         Begin
  1264.             WriteOut(' Error checking aborted...');
  1265.           ProgressBar1.Position:=0;
  1266.           StopButton:=False;
  1267.           CloseFile(Input);
  1268.                 If CheckBox3.Checked Then CloseFile(Log);
  1269.           EnableButtons;
  1270.             Exit;
  1271.         End;
  1272.         Until (Eof(Input)) Or (ChunkName='idx1');
  1273.         Str(Errors,Text);
  1274.         WriteOut(' Finished with '+ListBox1.Items.Strings[Item]+' .');
  1275.         WriteOut(' Number of errors: '+Text);
  1276.         WriteOut(' Done.');
  1277.       WriteOut('');
  1278.         If CheckBox3.Checked Then CloseFile(Log);
  1279.       ProgressBar1.Position:=100;
  1280.       CloseFile(Input);
  1281.       Inc(Item);
  1282.   Until Item=ListBox1.Items.Count;
  1283.     If CheckBox3.Checked Then
  1284.   Begin
  1285.       Logging:=False;
  1286.     Str(Errors,Text);
  1287.     WriteOut(' Finished with '+ListBox1.Items.Strings[Item]+' .');
  1288.         WriteOut(' Number of errors: '+Text);
  1289.         WriteOut(' Done.');
  1290.         WriteOut('');
  1291.   End;
  1292.     If Autoclearlist1.Checked Then ListBox1.Items.Clear;
  1293.     EnableButtons;
  1294. end;
  1295.  
  1296. procedure TForm1.Exit1Click(Sender: TObject);
  1297. begin
  1298.     Close;
  1299. end;
  1300.  
  1301. procedure TForm1.About1Click(Sender: TObject);
  1302. begin
  1303.     Form1.Enabled:=False;
  1304.     Form2.Show;
  1305. end;
  1306.  
  1307. procedure TForm1.StayTop(Sender: TObject);
  1308. begin
  1309.  
  1310.     If Stayontop1.Checked Then
  1311.   Begin
  1312.       Stayontop1.Checked:=Not(Stayontop1.Checked);
  1313. {$IFDEF WINDOWS}
  1314.     SetWindowPos(TForm1(Self).Handle,HWND_NOTOPMOST,0,0,0,0,SWP_NOSIZE+SWP_NOMOVE);
  1315. {$ENDIF}
  1316.   End
  1317.   Else
  1318.   Begin
  1319.       Stayontop1.Checked:=Not(Stayontop1.Checked);
  1320. {$IFDEF WINDOWS}
  1321.     SetWindowPos(TForm1(Self).Handle,HWND_TOPMOST,0,0,0,0,SWP_NOSIZE+SWP_NOMOVE);
  1322. {$ENDIF}
  1323.   End;
  1324. end;
  1325.  
  1326. procedure TForm1.FormCreate(Sender: TObject);
  1327. begin
  1328. {$IFDEF WINDOWS}
  1329.     DropFileTarget1.register(Form1);
  1330. {$ENDIF}
  1331.   If Tag=0 Then
  1332.   Begin
  1333.       GetDir(0,ConfigDir);
  1334. {$IFDEF WINDOWS}
  1335.          If Copy(ConfigDir,Length(ConfigDir),1)='\' Then AssignFile(Config,ConfigDir+'DivFix.ini')
  1336.     Else AssignFile(Config,ConfigDir+'\DivFix.ini');
  1337. {$ELSE}
  1338.          If Copy(ConfigDir,Length(ConfigDir),1)='/' Then AssignFile(Config,ConfigDir+'DivFix.ini')
  1339.     Else AssignFile(Config,ConfigDir+'/DivFix.ini');
  1340. {$ENDIF}
  1341.       {$I-}
  1342.       Reset(Config);
  1343.       {$I+}
  1344.         If IOResult=0 Then
  1345.       Begin
  1346.           While Not(Eof(Config)) Do
  1347.         Begin
  1348.                 Readln(Config,Text);
  1349.                 If Copy(Text,1,7)='LastDir' Then
  1350.           Begin
  1351.               Form1.OpenDialog1.InitialDir:=Copy(Text,9,Length(Text)-9);
  1352. {$IFDEF WINDOWS}
  1353.             CfgDir:=Form1.OpenDialog1.InitialDir+'\';
  1354. {$ELSE}
  1355.             CfgDir:=Form1.OpenDialog1.InitialDir+'/';
  1356. {$ENDIF}
  1357.           End;
  1358.                 If Copy(Text,1,7)='DestDir' Then
  1359.           Begin
  1360.               Form1.MaskEdit2.Text:=Copy(Text,9,Length(Text)-7);
  1361.             CfgDest:=Form1.MaskEdit2.Text;
  1362.           End;
  1363.                  If Copy(Text,1,9)='StayOnTop' Then
  1364.                  If Copy(Text,11,Length(Text)-9)='1' Then
  1365.               Begin
  1366.                         StayTop(Self);
  1367.               CfgStay:=True;
  1368.                  End
  1369.             Else CfgStay:=False;
  1370.                  If Copy(Text,1,9)='AutoClear' Then
  1371.                  If Copy(Text,11,Length(Text)-9)='1' Then
  1372.               Begin
  1373.                         Autoclear1.Checked:=True;
  1374.               CfgClear:=True;
  1375.                  End
  1376.             Else CfgClear:=False;
  1377.                  If Copy(Text,1,9)='ClearList' Then
  1378.                  If Copy(Text,11,Length(Text)-9)='1' Then
  1379.               Begin
  1380.                         Autoclearlist1.Checked:=True;
  1381.               CfgCList:=True;
  1382.                  End
  1383.             Else CfgCList:=False;
  1384.           If Copy(Text,1,12)='KeepOriginal' Then
  1385.                  If Copy(Text,14,Length(Text)-12)='1' Then
  1386.             Begin
  1387.                 Form1.CheckBox1.Checked:=True;
  1388.               CfgKeep:=True;
  1389.             End
  1390.             Else CfgKeep:=False;
  1391.           If Copy(Text,1,6)='CutOut' Then
  1392.               If Copy(Text,8,Length(Text)-6)='1' Then
  1393.                 If Form1.CheckBox2.Enabled Then
  1394.               Begin
  1395.                   Form1.CheckBox2.Checked:=True;
  1396.                 CfgCut:=True;
  1397.               End
  1398.               Else CfgCut:=False;
  1399.           If Copy(Text,1,9)='LogErrors' Then
  1400.               If Copy(Text,11,Length(Text)-9)='1' Then
  1401.             Begin
  1402.                 Form1.CheckBox3.Checked:=True;
  1403.               CfgLog:=True;
  1404.             End
  1405.             Else CfgLog:=False;
  1406.             End;
  1407.         CloseFile(Config);
  1408.       End;
  1409.   End;
  1410. end;
  1411.  
  1412. procedure TForm1.FormDestroy(Sender: TObject);
  1413. begin
  1414. {$IFDEF WINDOWS}
  1415.     DropFiletarget1.Unregister;
  1416. {$ENDIF}
  1417.   If Tag=0 Then
  1418. {$IFDEF WINDOWS}
  1419.       If (CfgDir<>OpenDialog1.InitialDir+'\') Or (CfgDest<>Form1.MaskEdit2.Text) Or
  1420.          (CfgStay<>Stayontop1.Checked) Or (CfgKeep<>CheckBox1.Checked) Or
  1421.        (CfgCut<>CheckBox2.Checked) Or (CfgLog<>CheckBox3.Checked) Or
  1422.        (CfgClear<>Autoclear1.Checked) Or (CfgCList<>Autoclearlist1.Checked) Then
  1423. {$ELSE}
  1424.       If (CfgDir<>OpenDialog1.InitialDir+'/') Or (CfgDest<>Form1.MaskEdit2.Text) Or
  1425.          (CfgStay<>Stayontop1.Checked) Or (CfgKeep<>CheckBox1.Checked) Or
  1426.        (CfgCut<>CheckBox2.Checked) Or (CfgLog<>CheckBox3.Checked) Or
  1427.        (CfgClear<>Autoclear1.Checked) Or (CfgCList<>Autoclearlist1.Checked) Then
  1428. {$ENDIF}
  1429.       Begin
  1430.           Rewrite(Config);
  1431. {$IFDEF WINDOWS}
  1432.         If OpenDialog1.InitialDir<>'' Then Writeln(Config,'LastDir='+OpenDialog1.InitialDir+'\')
  1433.       Else Writeln(Config,'LastDir=.\');
  1434.          If Form1.MaskEdit2.Text<>'' Then Writeln(Config,'DestDir='+Form1.MaskEdit2.Text)
  1435.       Else Writeln(Config,'DestDir=.\');
  1436. {$ELSE}
  1437.         If OpenDialog1.InitialDir<>'' Then Writeln(Config,'LastDir='+OpenDialog1.InitialDir+'/')
  1438.       Else Writeln(Config,'LastDir=./');
  1439.          If Form1.MaskEdit2.Text<>'' Then Writeln(Config,'DestDir='+Form1.MaskEdit2.Text)
  1440.       Else Writeln(Config,'DestDir=./');
  1441. {$ENDIF}
  1442.         If Stayontop1.Checked Then Writeln(Config,'StayOnTop=1')
  1443.         Else Writeln(Config,'StayOnTop=0');
  1444.       If Autoclear1.Checked Then Writeln(Config,'AutoClear=1')
  1445.         Else Writeln(Config,'AutoClear=0');
  1446.       If Autoclearlist1.Checked Then Writeln(Config,'ClearList=1')
  1447.            Else Writeln(Config,'ClearList=0');
  1448.          If CheckBox1.Checked Then Writeln(Config,'KeepOriginal=1')
  1449.         Else Writeln(Config,'KeepOriginal=0');
  1450.         If CheckBox2.Checked Then Writeln(Config,'CutOut=1')
  1451.         Else Writeln(Config,'CutOut=0');
  1452.         If CheckBox3.Checked Then Writeln(Config,'LogErrors=1')
  1453.         Else Writeln(Config,'LogErrors=0');
  1454.         CloseFile(Config);
  1455.         End;
  1456. end;
  1457.  
  1458. {$IFDEF WINDOWS}
  1459. procedure TForm1.DropFileTarget1Drop(Sender: TObject;
  1460.   ShiftState: TShiftState; Point: TPoint; var Effect: Integer);
  1461. begin
  1462.     ListBox1.Items.AddStrings(DropFileTarget1.Files);
  1463.   OpenDialog1.InitialDir:=Copy(ExtractFilePath(ListBox1.Items.Strings[0]),1,
  1464.       Length(ExtractFilePath(ListBox1.Items.Strings[0]))-1);
  1465. end;
  1466. {$ENDIF}
  1467.  
  1468. procedure TForm1.Button4Click(Sender: TObject);
  1469. begin
  1470.     StopButton:=True;
  1471. end;
  1472.  
  1473. procedure TForm1.CheckBox1Click(Sender: TObject);
  1474. begin
  1475.   CheckBox2.Enabled:=Not(CheckBox2.Enabled);
  1476.   SpeedButton2.Enabled:=Not(SpeedButton2.Enabled);
  1477.   Maskedit2.Enabled:=Not(MaskEdit2.Enabled);
  1478.   If Not(CheckBox2.Enabled) Then CheckBox2.Checked:=False;
  1479. end;
  1480.  
  1481. procedure TForm1.CheckBox3Click(Sender: TObject);
  1482. begin
  1483.   SpeedButton3.Enabled:=Not(SpeedButton3.Enabled);
  1484.   Maskedit3.Enabled:=Not(MaskEdit3.Enabled);
  1485.   If Not(CheckBox2.Enabled) Then CheckBox2.Checked:=False;
  1486. end;
  1487.  
  1488. procedure TForm1.ShowWebPage(Sender: TObject);
  1489. begin
  1490. {$IFDEF WINDOWS}
  1491.     ShellExecute(0,'open',pchar('http://divfix.maxeline.com'),nil,nil,SW_MAXIMIZE);
  1492. {$ENDIF}
  1493. end;
  1494.  
  1495. procedure TForm1.Button5Click(Sender: TObject);
  1496. begin
  1497.     If OpenDialog1.Execute Then
  1498.   Begin
  1499.       OpenDialog1.InitialDir:=Copy(ExtractFilePath(OpenDialog1.FileName),1,
  1500.       Length(ExtractFilePath(OpenDialog1.FileName))-1);
  1501.     ListBox1.Items.AddStrings(OpenDialog1.Files);
  1502.   End;
  1503. end;
  1504.  
  1505. procedure TForm1.Button6Click(Sender: TObject);
  1506. Var i    :    Cardinal;
  1507.  
  1508. begin
  1509.     i:=0;
  1510.   While i<=ListBox1.Items.Count-1 Do
  1511.       If ListBox1.Selected[i] Then ListBox1.Items.Delete(i)
  1512.     Else Inc(i);
  1513. end;
  1514.  
  1515. procedure TForm1.Button7Click(Sender: TObject);
  1516. begin
  1517.     ListBox1.Items.Clear;
  1518. end;
  1519.  
  1520. procedure TForm1.Clear1Click(Sender: TObject);
  1521. begin
  1522. {$IFDEF WINDOWS}
  1523.     RichEdit1.Clear;
  1524. {$ELSE}
  1525.     Memo1.Clear;
  1526. {$ENDIF}
  1527. end;
  1528.  
  1529. procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
  1530.   Shift: TShiftState);
  1531. begin
  1532. {$IFDEF WINDOWS}
  1533.     If Key=VK_INSERT Then Button5Click(nil);
  1534.   If Key=VK_DELETE Then Button6Click(nil);
  1535. {$ENDIF}
  1536. end;
  1537.  
  1538. procedure TForm1.Autoclear1Click(Sender: TObject);
  1539. begin
  1540.     Autoclear1.Checked:=Not(Autoclear1.Checked);
  1541. end;
  1542.  
  1543. procedure TForm1.Autoclearlist1Click(Sender: TObject);
  1544. begin
  1545.     Autoclearlist1.Checked:=Not(Autoclearlist1.Checked);
  1546. end;
  1547.  
  1548. end.
  1549.