unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ComCtrls, ExtCtrls, TeEngine, Series, TeeProcs, Chart,
  Spin, Math, idGlobal, XPMan, Grids, DSPack, ToolWin, ImgList, ShellApi, DirectShow9;

type
  TBasisImage = record
                 loaded : Boolean;
                 values : Array[0..7,0..7] of Integer;
                end;
  TBasisImages = Array[0..7,0..7] of TBasisImage;
  TForm1 = class(TForm)
    PageSourceControl1: TPageControl;
    ParametersTabSheet: TTabSheet;
    ImageTabSheet: TTabSheet;
    StatTabSheet: TTabSheet;
    GroupBox1: TGroupBox;
    ComboBox1: TComboBox;
    GroupBox2: TGroupBox;
    RadioButton1: TRadioButton;
    RadioButton2: TRadioButton;
    Edit1: TEdit;
    Button1: TButton;
    Button2: TButton;
    Panel1: TPanel;
    RadioButton3: TRadioButton;
    RadioButton4: TRadioButton;
    RadioButton5: TRadioButton;
    RadioButton6: TRadioButton;
    RadioButton7: TRadioButton;
    RadioButton8: TRadioButton;
    RadioButton9: TRadioButton;
    OpenDialog1: TOpenDialog;
    GroupBox3: TGroupBox;
    Image1: TImage;
    Chart1: TChart;
    Series1: TLineSeries;
    RadioButton10: TRadioButton;
    RadioButton11: TRadioButton;
    SpinEdit1: TSpinEdit;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    Label4: TLabel;
    SpinEdit2: TSpinEdit;
    Series2: TLineSeries;
    RadioButton12: TRadioButton;
    Label5: TLabel;
    Label6: TLabel;
    GroupBox4: TGroupBox;
    GroupBox5: TGroupBox;
    RadioButton13: TRadioButton;
    RadioButton14: TRadioButton;
    RadioButton15: TRadioButton;
    RadioButton16: TRadioButton;
    Chart2: TChart;
    Label7: TLabel;
    SpinEdit3: TSpinEdit;
    Label8: TLabel;
    SpinEdit4: TSpinEdit;
    Label9: TLabel;
    SpinEdit5: TSpinEdit;
    Label10: TLabel;
    RadioButton17: TRadioButton;
    RadioButton18: TRadioButton;
    SpinEdit6: TSpinEdit;
    Panel2: TPanel;
    RadioButton19: TRadioButton;
    RadioButton20: TRadioButton;
    Label12: TLabel;
    SpinEdit7: TSpinEdit;
    SpinEdit8: TSpinEdit;
    Label13: TLabel;
    Button3: TButton;
    Image2: TImage;
    Image3: TImage;
    RadioButton21: TRadioButton;
    RadioButton22: TRadioButton;
    RadioButton23: TRadioButton;
    Image4: TImage;
    GroupBox6: TGroupBox;
    RadioButton25: TRadioButton;
    RadioButton24: TRadioButton;
    ComboBox2: TComboBox;
    GroupBox7: TGroupBox;
    Label14: TLabel;
    Label15: TLabel;
    Label16: TLabel;
    Label17: TLabel;
    Label18: TLabel;
    Label19: TLabel;
    Label20: TLabel;
    Label21: TLabel;
    Label22: TLabel;
    Label23: TLabel;
    GroupBox8: TGroupBox;
    Label24: TLabel;
    Label26: TLabel;
    Label25: TLabel;
    Label27: TLabel;
    Chart3: TChart;
    Series4: TLineSeries;
    GroupBox9: TGroupBox;
    GroupBox10: TGroupBox;
    Image5: TImage;
    Label28: TLabel;
    Panel3: TPanel;
    RadioButton26: TRadioButton;
    RadioButton27: TRadioButton;
    XPManifest1: TXPManifest;
    Label29: TLabel;
    Panel4: TPanel;
    RadioButton28: TRadioButton;
    RadioButton29: TRadioButton;
    Label30: TLabel;
    SpinEdit9: TSpinEdit;
    StringGrid1: TStringGrid;
    Label31: TLabel;
    RadioButton30: TRadioButton;
    Series3: TLineSeries;
    Panel5: TPanel;
    RadioButton31: TRadioButton;
    SpinEdit10: TSpinEdit;
    RadioButton32: TRadioButton;
    SpinEdit11: TSpinEdit;
    RadioButton33: TRadioButton;
    SpinEdit12: TSpinEdit;
    Button4: TButton;
    GroupBox11: TGroupBox;
    Edit2: TEdit;
    Button5: TButton;
    Button6: TButton;
    OpenDialog2: TOpenDialog;
    GroupBox12: TGroupBox;
    GroupBox13: TGroupBox;
    Memo1: TMemo;
    Label11: TLabel;
    Label32: TLabel;
    Panel6: TPanel;
    RadioButton34: TRadioButton;
    RadioButton35: TRadioButton;
    RadioButton36: TRadioButton;
    FilterGraph: TFilterGraph;
    VideoWindow1: TVideoWindow;
    ImageList1: TImageList;
    ToolBar1: TToolBar;
    ToolButton1: TToolButton;
    ToolButton2: TToolButton;
    ToolButton3: TToolButton;
    ToolButton4: TToolButton;
    ToolButton5: TToolButton;
    ToolButton6: TToolButton;
    ToolButton7: TToolButton;
    Label33: TLabel;
    SpinEdit13: TSpinEdit;
    Label34: TLabel;
    SpinEdit14: TSpinEdit;
    Label35: TLabel;
    ComboBox3: TComboBox;
    Label36: TLabel;
    SpinEdit15: TSpinEdit;
    Label37: TLabel;
    SpinEdit16: TSpinEdit;
    Button7: TButton;
    Label38: TLabel;
    DSTrackBar1: TDSTrackBar;
    Button8: TButton;
    Memo2: TMemo;
    procedure ComboBox1Change(Sender: TObject);
    procedure RadioButton1Click(Sender: TObject);
    procedure RadioButton2Click(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure RadioButton11Click(Sender: TObject);
    procedure RadioButton10Click(Sender: TObject);
    procedure SpinEdit1Change(Sender: TObject);
    procedure SpinEdit2Change(Sender: TObject);
    procedure RadioButton12Click(Sender: TObject);
    procedure RadioButton14Click(Sender: TObject);
    procedure RadioButton15Click(Sender: TObject);
    procedure RadioButton16Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure SpinEdit4Change(Sender: TObject);
    procedure SpinEdit5Change(Sender: TObject);
    procedure Label12Click(Sender: TObject);
    procedure RadioButton17Click(Sender: TObject);
    procedure RadioButton18Click(Sender: TObject);
    procedure SpinEdit6Change(Sender: TObject);
    procedure SpinEdit8Change(Sender: TObject);
    procedure RadioButton19Click(Sender: TObject);
    procedure RadioButton20Click(Sender: TObject);
    procedure SpinEdit7Change(Sender: TObject);
    procedure Button3Click(Sender: TObject);
    procedure RadioButton21Click(Sender: TObject);
    procedure RadioButton22Click(Sender: TObject);
    procedure RadioButton23Click(Sender: TObject);
    procedure RadioButton24Click(Sender: TObject);
    procedure RadioButton25Click(Sender: TObject);
    procedure ComboBox2Change(Sender: TObject);
    procedure RadioButton29Click(Sender: TObject);
    procedure RadioButton28Click(Sender: TObject);
    procedure RadioButton26Click(Sender: TObject);
    procedure RadioButton27Click(Sender: TObject);
    procedure StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
      Rect: TRect; State: TGridDrawState);
    procedure StringGrid1SelectCell(Sender: TObject; ACol, ARow: Integer;
      var CanSelect: Boolean);
    procedure Image2Click(Sender: TObject);
    procedure Image3Click(Sender: TObject);
    procedure Image4Click(Sender: TObject);
    procedure Chart2Click(Sender: TObject);
    procedure Chart2ClickAxis(Sender: TCustomChart; Axis: TChartAxis;
      Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
    procedure Chart2ClickBackground(Sender: TCustomChart;
      Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
    procedure Chart2ClickLegend(Sender: TCustomChart; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure Chart2ClickSeries(Sender: TCustomChart; Series: TChartSeries;
      ValueIndex: Integer; Button: TMouseButton; Shift: TShiftState; X,
      Y: Integer);
    procedure Chart2Enter(Sender: TObject);
    procedure Chart2MouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure RadioButton30Click(Sender: TObject);
    procedure SpinEdit10Change(Sender: TObject);
    procedure SpinEdit11Change(Sender: TObject);
    procedure RadioButton31Click(Sender: TObject);
    procedure RadioButton32Click(Sender: TObject);
    procedure RadioButton33Click(Sender: TObject);
    procedure SpinEdit12Change(Sender: TObject);
    procedure Button4Click(Sender: TObject);
    procedure Button5Click(Sender: TObject);
    procedure Button6Click(Sender: TObject);
    procedure ToolButton1Click(Sender: TObject);
    procedure ToolButton3Click(Sender: TObject);
    procedure ToolButton5Click(Sender: TObject);
    procedure ToolButton7Click(Sender: TObject);
    procedure Button7Click(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure Button8Click(Sender: TObject);
    procedure VideoWindow1Click(Sender: TObject);

  private
    { Private declarations }
  public
    differences:array [0..511] of Integer;
    DiffSum:LongInt;
    threshold,needed:Integer;
    width,height:Integer;
    DiffTable:array [0..512] of integer;
    Diff_used:Integer;
    Reds,Greens,Blues:Array [0..1600,0..1600] of Integer;
    dropped:Array[0..15,0..15] of Integer;
    AdamarImages:TBasisImages;
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

uses Unit2;

{$R *.dfm}
procedure DefaultDropped(total:Integer;moved:Boolean);
var
i,j:Integer;
begin
For i:=0 to 15 do
For j:=0 to 15 do Form1.dropped[i,j]:=0;
If (total=8) and (moved=False) then begin
                                    Form1.dropped[0,0]:=1;
                                    Form1.dropped[1,0]:=1;
                                    Form1.dropped[2,0]:=1;
                                    Form1.dropped[3,0]:=1;
                                    Form1.dropped[0,1]:=1;
                                    Form1.dropped[1,1]:=1;
                                    Form1.dropped[2,1]:=1;
                                    Form1.dropped[3,1]:=1;
                                    Form1.dropped[5,0]:=1;
                                    Form1.dropped[6,0]:=1;
                                    Form1.dropped[7,0]:=1;
                                    Form1.dropped[0,2]:=1;
                                    Form1.dropped[1,2]:=1;
                                    Form1.dropped[2,2]:=1;
                                    Form1.dropped[0,3]:=1;
                                    Form1.dropped[1,3]:=1;
                                    Form1.dropped[0,5]:=1;
                                    Form1.dropped[0,6]:=1;
                                    Form1.dropped[0,7]:=1;
                                    end;
If (total=4) and (moved=True) then begin
                                    Form1.dropped[4,4]:=1;
                                    Form1.dropped[4,5]:=1;
                                    Form1.dropped[4,6]:=1;
                                    Form1.dropped[4,7]:=1;
                                    Form1.dropped[5,4]:=1;
                                    Form1.dropped[5,5]:=1;
                                    Form1.dropped[6,4]:=1;
                                    Form1.dropped[7,4]:=1;
                                    end;
end;

{procedure ExecNewProcess(ProgramName : String);
var
  StartInfo  : TStartupInfo;
  ProcInfo   : TProcessInformation;
  CreateOK   : Boolean;
begin

  // fill with known state
  FillChar(StartInfo,SizeOf(TStartupInfo),#0);
  FillChar(ProcInfo,SizeOf(TProcessInformation),#0);
  StartInfo.cb := SizeOf(TStartupInfo);

  CreateOK := CreateProcess(nil, PChar(ProgramName), nil, nil,False,
              CREATE_NEW_PROCESS_GROUP+NORMAL_PRIORITY_CLASS,
              nil, nil, StartInfo, ProcInfo);

  // check to see if successful
  if CreateOK then
    //may or may not be needed. Usually wait for child processes
    WaitForSingleObject(ProcInfo.hProcess, INFINITE);
end; }

function GetDosOutput(CommandLine: string; Work: string = 'C:\'): string;
var
  SA: TSecurityAttributes;
  SI: TStartupInfo;
  PI: TProcessInformation;
  StdOutPipeRead, StdOutPipeWrite: THandle;
  WasOK: Boolean;
  Buffer: array[0..255] of AnsiChar;
  BytesRead: Cardinal;
  WorkDir: string;
  Handle: Boolean;
begin
  Result := '';
  with SA do begin
    nLength := SizeOf(SA);
    bInheritHandle := True;
    lpSecurityDescriptor := nil;
  end;
  CreatePipe(StdOutPipeRead, StdOutPipeWrite, @SA, 0);
  try
    with SI do
    begin
      FillChar(SI, SizeOf(SI), 0);
      cb := SizeOf(SI);
      dwFlags := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES;
      wShowWindow := SW_HIDE;
      hStdInput := GetStdHandle(STD_INPUT_HANDLE); // don't redirect stdin
      hStdOutput := StdOutPipeWrite;
      hStdError := StdOutPipeWrite;
    end;
    WorkDir := Work;
    Handle := CreateProcess(nil, PChar('cmd.exe /C ' + CommandLine),
                            nil, nil, True, 0, nil,
                            PChar(WorkDir), SI, PI);
    CloseHandle(StdOutPipeWrite);
    if Handle then
      try
        repeat
          WasOK := ReadFile(StdOutPipeRead, Buffer, 255, BytesRead, nil);
          if BytesRead > 0 then
          begin
            Buffer[BytesRead] := #0;
            Result := Result + Buffer;
          end;
        until not WasOK or (BytesRead = 0);
        WaitForSingleObject(PI.hProcess, INFINITE);
      finally
        CloseHandle(PI.hThread);
        CloseHandle(PI.hProcess);
      end;
  finally
    CloseHandle(StdOutPipeRead);
  end;
end;

procedure LoadAdamarBasisImage(size,x,y:Integer);
var
Bitmap:TBitmap;
tmpstr:String;
i,j:Integer;
currclr:TColor;
begin
Bitmap:=TBitmap.Create;
tmpstr:=ExtractFileDir(Application.ExeName)+'\Adamar_basis_images\'+IntToStr(size)+'x'+IntToStr(size)+'\phi'+IntToStr(x)+IntToStr(y)+'.bmp';
Bitmap.LoadFromFile(tmpstr);
For i:=0 to size-1 do
For j:=0 to size-1 do begin
                      currclr:=Bitmap.Canvas.Pixels[i,j];
                      If currclr=0 then Form1.AdamarImages[x,y].Values[i,j]:=-1
                                   else Form1.AdamarImages[x,y].Values[i,j]:=1;
                      end;
Form1.AdamarImages[x,y].Loaded:=True;
Bitmap.Destroy;
end;

procedure QuickSort(var A: array of Integer; iLo, iHi: Integer) ;
 var
   Lo, Hi, Pivot, T: Integer;
 begin
   Lo := iLo;
   Hi := iHi;
   Pivot := A[(Lo + Hi) div 2];
   repeat
     while A[Lo] < Pivot do Inc(Lo) ;
     while A[Hi] > Pivot do Dec(Hi) ;
     if Lo <= Hi then
     begin
       T := A[Lo];
       A[Lo] := A[Hi];
       A[Hi] := T;
       Inc(Lo) ;
       Dec(Hi) ;
     end;
   until Lo > Hi;
   if Hi > iLo then QuickSort(A, iLo, Hi) ;
   if Lo < iHi then QuickSort(A, Lo, iHi) ;
 end;

//возвращаем номер элемента в difftable
function FindClosestDiff(Diff:Integer):Integer;
var
i:Integer;
opt:Integer;
resultf:Integer;
begin
opt:=600;
resultf:=-1;
for i:=0 to Length(Form1.DiffTable)-1 do if Abs(Form1.difftable[i]-diff)<opt then begin
                                                                                  opt:=Abs(Form1.difftable[i]-diff);
                                                                                  resultf:=i;
                                                                                  end;
FindClosestDiff:=resultf;
end;

procedure TForm1.ComboBox1Change(Sender: TObject);
begin
GroupBox3.Visible:=False;
GroupBox4.Visible:=False;
GroupBox5.Visible:=False;
GroupBox9.Visible:=False;
GroupBox10.Visible:=False;
GroupBox11.Visible:=False;
GroupBox12.Visible:=False;
GroupBox13.Visible:=False;
Button6.Enabled:=False;
FilterGraph.ClearGraph;
If Combobox1.ItemIndex<4 then Groupbox2.Visible:=True
                         else begin
                              Groupbox2.Visible:=False;
                              GroupBox11.Visible:=True;
                              end;
If Combobox1.ItemIndex=0 then begin
                              Label13.Caption:='Линейный квантователь не отсечет наиболее резкие изменения цветов.'+#10+#13+'Разностные отсчеты передадутся точно, но информации будет передано больше, чем без ДИКМ.';
                              end;
end;

procedure TForm1.RadioButton1Click(Sender: TObject);
begin
If RadioButton1.Checked then begin
                             RadioButton3.Enabled:=True;
                             RadioButton4.Enabled:=True;
                             RadioButton5.Enabled:=True;
                             RadioButton6.Enabled:=True;
                             RadioButton7.Enabled:=True;
                             RadioButton8.Enabled:=True;
                             RadioButton9.Enabled:=True;
                             Edit1.Enabled:=False;
                             Button1.Enabled:=False;
                             end
                        else begin
                             RadioButton3.Enabled:=False;
                             RadioButton4.Enabled:=False;
                             RadioButton5.Enabled:=False;
                             RadioButton6.Enabled:=False;
                             RadioButton7.Enabled:=False;
                             RadioButton8.Enabled:=False;
                             RadioButton9.Enabled:=False;
                             Edit1.Enabled:=True;
                             Button1.Enabled:=True;
                             end;
end;

procedure TForm1.RadioButton2Click(Sender: TObject);
begin
If RadioButton2.Checked=false then begin
                                   RadioButton3.Enabled:=True;
                                   RadioButton4.Enabled:=True;
                                   RadioButton5.Enabled:=True;
                                   RadioButton6.Enabled:=True;
                                   RadioButton7.Enabled:=True;
                                   RadioButton8.Enabled:=True;
                                   RadioButton9.Enabled:=True;
                                   Edit1.Enabled:=False;
                                   Button1.Enabled:=False;
                                   end
                              else begin
                                   RadioButton3.Enabled:=False;
                                   RadioButton4.Enabled:=False;
                                   RadioButton5.Enabled:=False;
                                   RadioButton6.Enabled:=False;
                                   RadioButton7.Enabled:=False;
                                   RadioButton8.Enabled:=False;
                                   RadioButton9.Enabled:=False;
                                   Edit1.Enabled:=True;
                                   Button1.Enabled:=True;
                                   end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
If OpenDialog1.Execute then Edit1.Text:=OpenDialog1.FileName;
end;

procedure TForm1.Button2Click(Sender: TObject);
var
ratio:Real;
i,j:Integer;
diff:Integer;
currclr:TColor;
r,g,b: Byte;
pr,pg,pb:Byte;
begin
If Combobox1.ItemIndex=0 then begin
Image1.AutoSize:=True;
If RadioButton1.Checked then begin
                             //If RadioButton3.Checked then Image1.Picture.LoadFromFile();
                             If RadioButton4.Checked then Image1.Picture.LoadFromFile(ExtractFileDir(Application.ExeName)+'\Pictures\BW Picture.bmp');
                             If RadioButton5.Checked then Image1.Picture.LoadFromFile(ExtractFileDir(Application.ExeName)+'\Pictures\Color Picture.bmp');
                             If RadioButton7.Checked then Image1.Picture.LoadFromFile(ExtractFileDir(Application.ExeName)+'\Pictures\Color Stripes.bmp');
                             If RadioButton6.Checked then Image1.Picture.LoadFromFile(ExtractFileDir(Application.ExeName)+'\Pictures\Checkers.bmp');
                             If RadioButton13.Checked then Image1.Picture.LoadFromFile(ExtractFileDir(Application.ExeName)+'\Pictures\Checkers-small.bmp');
                             If RadioButton8.Checked then Image1.Picture.LoadFromFile(ExtractFileDir(Application.ExeName)+'\Pictures\High-contrast Letters.bmp');
                             If RadioButton9.Checked then Image1.Picture.LoadFromFile(ExtractFileDir(Application.ExeName)+'\Pictures\Low-contrast Letters.bmp');
                             end
                        else begin
                             try
                             Image1.Picture.LoadFromFile(Edit1.Text);
                             except
                             Application.MessageBox('Ошибка при загрузке изображения','Ошибка',mb_ok  or MB_ICONERROR);
                             end;
                             end;
Image1.Visible:=False;
RadioButton10.Checked:=True;
width:=Image1.Width;
height:=Image1.Height;
ratio:=width/height;
If (width>1599) or (height>1599) then begin
                                      Application.MessageBox('Максимальный размер изображения для обработки - 1600х1600!','Ошибка',mb_ok  or MB_ICONERROR);
                                      exit;
                                      end;

for i:=0 to 511 do differences[i]:=0;
For i:=0 to Image1.Height-1 do begin
                             currclr:=Image1.Picture.Bitmap.Canvas.Pixels[0,i];
                             pr := currclr and $FF;
                             pg := (currclr shr 8) and $FF;
                             pb := (currclr shr 16) and $FF;
                             For j:=1 to Image1.Width-1 do begin
                                                         currclr:=Image1.Picture.Bitmap.Canvas.Pixels[j,i];
                                                         r := currclr and $FF;
                                                         g := (currclr shr 8) and $FF;
                                                         b := (currclr shr 16) and $FF;
                                                         diff:=r-pr;
                                                         differences[diff+255]:=differences[diff+255]+1;
                                                         diff:=b-pb;
                                                         differences[diff+255]:=differences[diff+255]+1;
                                                         diff:=g-pg;
                                                         differences[diff+255]:=differences[diff+255]+1;
                                                         pr:=r;
                                                         pg:=g;
                                                         pb:=b;
                                                         end;
                             end;
for i:=0 to 511 do differences[i]:=Trunc(differences[i]/3);
DiffSum:=0;
for i:=0 to 511 do diffsum:=diffsum+differences[i];
SpinEdit1.MaxValue:=DiffSum;
Chart1.Series[0].Clear;
Chart1.Series[1].Clear;
for i:=0 to 511 do Chart1.Series[0].AddXY(i-255,differences[i]);

Image1.AutoSize:=False;
Image1.Stretch:=True;
If ratio<4/3 then begin
                  Image1.width:=300;
                  Image1.height:=Round(300/ratio);
                  end
             else begin
                  Image1.height:=200;
                  Image1.width:=Round(ratio*200);
                  end;
Image1.Visible:=True;
GroupBox3.Visible:=True;
GroupBox4.Visible:=True;
GroupBox5.Visible:=True;
RadioButton30.Checked:=True;
RadioButton30Click(Self);
end;

If Combobox1.ItemIndex=1 then begin
Image5.AutoSize:=True;
If RadioButton1.Checked then begin
                             //If RadioButton3.Checked then Image1.Picture.LoadFromFile();
                             If RadioButton4.Checked then Image5.Picture.LoadFromFile(ExtractFileDir(Application.ExeName)+'\Pictures\BW Picture.bmp');
                             If RadioButton5.Checked then Image5.Picture.LoadFromFile(ExtractFileDir(Application.ExeName)+'\Pictures\Color Picture.bmp');
                             If RadioButton7.Checked then Image5.Picture.LoadFromFile(ExtractFileDir(Application.ExeName)+'\Pictures\Color Stripes.bmp');
                             If RadioButton6.Checked then Image5.Picture.LoadFromFile(ExtractFileDir(Application.ExeName)+'\Pictures\Checkers.bmp');
                             If RadioButton13.Checked then Image5.Picture.LoadFromFile(ExtractFileDir(Application.ExeName)+'\Pictures\Checkers-small.bmp');
                             If RadioButton8.Checked then Image5.Picture.LoadFromFile(ExtractFileDir(Application.ExeName)+'\Pictures\High-contrast Letters.bmp');
                             If RadioButton9.Checked then Image5.Picture.LoadFromFile(ExtractFileDir(Application.ExeName)+'\Pictures\Low-contrast Letters.bmp');
                             end
                        else begin
                             try
                             Image5.Picture.LoadFromFile(Edit1.Text);
                             except
                             Application.MessageBox('Ошибка при загрузке изображения','Ошибка',mb_ok  or MB_ICONERROR);
                             end;
                             end;
Image1.Visible:=False;
RadioButton10.Checked:=True;
width:=Image1.Width;
height:=Image1.Height;
ratio:=width/height;
If (width>1599) or (height>1599) then begin
                                      Application.MessageBox('Максимальный размер изображения для обработки - 1600х1600!','Ошибка',mb_ok  or MB_ICONERROR);
                                      exit;
                                      end;
Image5.AutoSize:=False;
Image5.Stretch:=True;
If ratio<4/3 then begin
                  Image5.width:=364;
                  Image5.height:=Round(364/ratio);
                  end
             else begin
                  Image5.height:=273;
                  Image5.width:=Round(ratio*273);
                  end;
Image5.Visible:=True;
GroupBox9.Visible:=True;
GroupBox10.Visible:=True;
GroupBox5.Visible:=True;
RadioButton26Click(Self);
end;


end;

procedure TForm1.RadioButton11Click(Sender: TObject);
begin
If Radiobutton11.Checked then SpinEdit1.Enabled:=True
                         else SpinEdit1.Enabled:=False;
Spinedit1Change(Self);
end;

procedure TForm1.RadioButton10Click(Sender: TObject);
var
i:Integer;
begin
If Radiobutton11.Checked then SpinEdit1.Enabled:=True
                         else SpinEdit1.Enabled:=False;
Chart1.Series[0].Clear;
for i:=0 to 511 do Chart1.Series[0].AddXY(i-255,differences[i]);
Label3.Caption:='Сейчас на графике отображены 100% разностных отсчетов.';
end;

procedure TForm1.SpinEdit1Change(Sender: TObject);
var
i:Integer;
first,last:Integer;
cursum:LongInt;
begin
try
Chart1.Series[0].Clear;
last:=-1;
first:=512;
For i:=0 to 511 do If differences[i]>SpinEdit1.Value then last:=i;
For i:=511 downto 0 do If differences[i]>SpinEdit1.Value then first:=i;
If last>=0 then begin
               cursum:=0;
               If last=511 then last:=510;
               for i:=first to last+1 do If differences[i]>SpinEdit1.Value then begin
                                                                            Chart1.Series[0].AddXY(i-255,differences[i]);
                                                                            cursum:=cursum+differences[i];
                                                                            end
                                                                       else Chart1.Series[0].AddXY(i-255,0);
               Label3.Caption:='Сейчас на графике отображены '+IntToStr(Trunc(cursum/diffsum*100))+'% разностных отсчетов.';
               end
          else begin
               Label3.Caption:='В выбранном изображении ни один разностный отсчет не'+#10+#13+'появляется заданное число раз.';
               end;
except
end;
end;

procedure TForm1.SpinEdit2Change(Sender: TObject);
var
max:Integer;
i,j:Integer;
cursum:LongInt;
begin
try
max:=0;
j:=Trunc(Power(2,SpinEdit2.Value)/2);
For i:=0 to 511 do If differences[i]>max then max:=differences[i];
Chart1.Series[1].Clear;
Chart1.Series[1].AddXY(j,max);
Chart1.Series[1].AddXY(j+1,0);
Chart1.Series[1].AddXY(-1*j-1,0);
Chart1.Series[1].AddXY(-1*j,max);
If Spinedit2.Value<9 then begin
                          cursum:=0;
                          for i:=255-j to 255+j do cursum:=cursum+differences[i];
                          Label6.Caption:=IntToStr(Trunc(cursum/diffsum*100))+'% разностных отсчетов';
                          end
                     else Label6.Caption:='100% разностных отсчетов';
except
end;
end;

procedure TForm1.RadioButton12Click(Sender: TObject);
begin
RadioButton10Click(Self);
SpinEdit2Change(Self);
end;

procedure TForm1.RadioButton14Click(Sender: TObject);
begin
If RadioButton14.Checked then begin
                              SpinEdit3.Enabled:=False;
                              SpinEdit4.Enabled:=False;
                              SpinEdit5.Enabled:=False;
                              Chart2.Series[0].Clear;
                              end;
end;

procedure TForm1.RadioButton15Click(Sender: TObject);
begin
If RadioButton15.Checked then begin
                              SpinEdit3.Enabled:=True;
                              SpinEdit4.Enabled:=True;
                              SpinEdit5.Enabled:=True;
                              SpinEdit4Change(Self);
                              end;
end;

procedure TForm1.RadioButton16Click(Sender: TObject);
begin
If RadioButton16.Checked then begin
                              SpinEdit3.Enabled:=True;
                              SpinEdit4.Enabled:=True;
                              SpinEdit5.Enabled:=True;
                              SpinEdit4Change(Self);
                              end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
randomize;

{ImageTabSheet.Visible:=False;
StatTabSheet.Visible:=False;}
end;

procedure TForm1.SpinEdit4Change(Sender: TObject);
var
randres:array [-255..255] of Integer;
i:Integer;
temp:Integer;
rand:Integer;
begin
If Chart2.AnimatedZoom then
try
Chart2.Series[0].Clear;
for i:=-255 to 255 do randres[i]:=0;
If RadioButton15.Checked then begin
                              temp:=SpinEdit4.Value-Trunc(SpinEdit5.Value/2);
                              for i:=0 to 1000000 do begin
                                                    rand:=temp+Random(SpinEdit5.Value);
                                                    if (rand>=-255) and (rand<=255) then randres[rand]:=randres[rand]+1;
                                                    end;
                              end;
If RadioButton16.Checked then begin
                              temp:=Round(SpinEdit4.Value-SpinEdit5.Value/2);
                              for i:=0 to 100000 do begin
                                                    rand:=temp+Round((Random(SpinEdit5.Value)+Random(Spinedit5.Value)+Random(Spinedit5.Value))/3);
                                                    if (rand>=-255) and (rand<=255) then randres[rand]:=randres[rand]+1;
                                                    end;
                              end;
for i:=-254 to 254 do Chart2.Series[0].AddXY(i,Round((randres[i-1]+randres[i]+randres[i+1])/3));
except
end;
end;

procedure TForm1.SpinEdit5Change(Sender: TObject);
begin
SpinEdit4Change(Self);
end;

procedure TForm1.Label12Click(Sender: TObject);
begin
RadioButton20.Checked:=True;
end;

procedure TForm1.RadioButton17Click(Sender: TObject);
begin
If RadioButton17.Checked then begin
                              SpinEdit6.Enabled:=True;
                              RadioButton19.Enabled:=False;
                              RadioButton20.Enabled:=False;
                              label12.enabled:=False;
                              SpinEdit7.Enabled:=False;
                              SpinEdit8.Enabled:=False;
                              SpinEdit10.Enabled:=False;
                              RadioButton31.Enabled:=False;
                              RadioButton32.Enabled:=False;
                              SpinEdit11.Enabled:=False;
                              RadioButton33.Enabled:=False;
                              SpinEdit12.Enabled:=False;
                              end;
end;

procedure TForm1.RadioButton18Click(Sender: TObject);
begin
If RadioButton19.Checked then begin
                              SpinEdit6.Enabled:=False;
                              RadioButton19.Enabled:=True;
                              RadioButton20.Enabled:=True;
                              SpinEdit10.Enabled:=False;
                              RadioButton31.Enabled:=False;
                              RadioButton32.Enabled:=False;
                              SpinEdit11.Enabled:=False;
                              RadioButton33.Enabled:=True;
                              If RadioButton19.Checked then begin
                                                            SpinEdit7.Enabled:=True;
                                                            SpinEdit7Change(Self);
                                                            end;
                              If RadioButton20.Checked then begin
                                                            label12.enabled:=True;
                                                            SpinEdit8.Enabled:=True;
                                                            SpinEdit8Change(Self);
                                                            end;
                              If RadioButton33.Checked then begin
                                                            SpinEdit12.Enabled:=True;
                                                            SpinEdit12Change(Self);
                                                            end;
                              end;
end;

procedure TForm1.SpinEdit6Change(Sender: TObject);
var
i,j:Integer;
cursum:Longint;
begin
Radiobutton12.Checked:=True;
SpinEdit2.Value:=SpinEdit6.Value;
If Spinedit2.Value<9 then begin
                          cursum:=0;
                          j:=Trunc(Power(2,SpinEdit2.Value)/2);
                          for i:=255-j to 255+j do cursum:=cursum+differences[i];
                          Label13.Caption:='Линейный квантователь отсечет наиболее резкие изменения цветов.'+#10+#13+'Точно будет передано '+IntToStr(Trunc(cursum/diffsum*100))+'% разностных отсчетов';
                          end
                     else Label13.Caption:='Линейный квантователь не отсечет наиболее резкие изменения цветов.'+#10+#13+'Разностные отсчеты передадутся точно, но информации будет передано больше, чем без ДИКМ.';
end;

procedure TForm1.SpinEdit8Change(Sender: TObject);
var
i:Integer;
tmp:Real;
resultn:integer;
cursum:LongInt;
begin
try
Chart1.Series[1].Clear;
Chart1.Series[1].AddXY(-255,SpinEdit8.Value);
Chart1.Series[1].AddXy(255,SpinEdit8.Value);

needed:=0;
cursum:=0;
for i:=0 to 511 do begin
                   If differences[i]>=SpinEdit8.Value then begin
                                                           needed:=needed+1;
                                                           cursum:=cursum+differences[i];
                                                           end;
                   end;
tmp:=ln(needed)/ln(2);
If Trunc(tmp)<>tmp then resultn:=Trunc(tmp)+1
                   else resultn:=Trunc(tmp);
Label13.Caption:='Для кодирования изображения с заданным критерием значимости нужно представлять '+IntToStr(needed)+' различных значений '+#10+#13+'разностных отсчетов, для чего нужно '+IntToStr(resultn)+' бит на каждый отсчет. Точно будут переданы '+IntToStr(Trunc(cursum/diffsum*100))+'% разностных отсчетов.';
except
end;
end;

procedure TForm1.RadioButton19Click(Sender: TObject);
begin
If (RadioButton19.Checked) and (RadioButton18.Checked) then begin
                                                            SpinEdit7.Enabled:=True;
                                                            SpinEdit8.Enabled:=False;
                                                            SpinEdit12.Enabled:=False;
                                                            end;
end;

procedure TForm1.RadioButton20Click(Sender: TObject);
begin
If (RadioButton20.Checked) and (RadioButton18.Checked) then begin
                                                            SpinEdit7.Enabled:=False;
                                                            SpinEdit8.Enabled:=True;
                                                            SpinEdit12.Enabled:=False;
                                                            Label12.Enabled:=True;
                                                            SpinEdit8Change(Self);
                                                            end;
end;

procedure TForm1.SpinEdit7Change(Sender: TObject);
var
tmparr:array[0..511] of integer;
tmp,i:Integer;
cursum:LongInt;
begin
For tmp:=0 to 511 do tmparr[tmp]:=differences[tmp];
QuickSort(tmparr,Low(differences),High(differences));
tmp:=trunc(512-Power(2,SpinEdit7.Value));
threshold:=tmparr[tmp];
Label13.Caption:='Критерий значимости для заданной длины разностного отсчета:'+#10+#13+'Разностный отсчет должен встречаться не менее '+IntToStr(threshold)+' раз.';
Chart1.Series[1].Clear;
Chart1.Series[1].AddXY(-255,threshold+1);
Chart1.Series[1].AddXy(255,threshold+1);
cursum:=0;
For i:=tmp to 511 do cursum:=cursum+tmparr[i];
Label13.Caption:=Label13.Caption+' Будут точно переданы '+IntToStr(Trunc(cursum/diffsum*100))+'% разностных отсчетов.';
end;

procedure TForm1.Button3Click(Sender: TObject);
var
i,j,k:Integer;
tmp:integer;
tmpr:Real;
currclr:TColor;
r,g,b: Byte;
pr,pg,pb:Byte;
diff:Integer;
Bitmap:TBitmap;
begin
Bitmap:=Tbitmap.Create;
//difftable - массив, устанавливающий связь между номером уровня квантования (номером элемента в массиве) и размером кодируемого изменения
//для линейного квантователя это не нужно, поэтому прописываются просто фиксированные значения в том количестве, что задано доступным числом бит
//Для адаптивного квантователя по критерию значимости нужно needed элементов. Значения их узнаем из элементов differences, отвечающих требуемому критерию значимости
//Для адаптивного квантователя по критерию доступного числа бит на разностный отсчет количество элементов задается пользователем, а хранящиеся в них разности считываются аналитически.
//Готовим массив уровней квантования
for i:=0 to 511 do difftable[i]:=4096;
If (radiobutton30.Checked) and (radiobutton31.checked) then begin
                                                            tmp:=Trunc(Power(2,SpinEdit10.Value));
                                                            diff_used:=tmp;
                                                            j:=Round(255/(Power(2,SpinEdit10.Value)/2+1));
                                                            For i:=0 to Round(Power(2,SpinEdit10.Value)/2)-1 do begin
                                                                                                                difftable[i]:=(i+1)*j;
                                                                                                                difftable[tmp-1-i]:=-(i+1)*j;
                                                                                                                end;
                                                            end;
If (radiobutton30.Checked) and (radiobutton32.checked) then begin
                                                            tmp:=Trunc(Power(2,SpinEdit10.Value));
                                                            diff_used:=tmp;
                                                            For i:=0 to Round(Power(2,SpinEdit10.Value)/2)-1 do begin
                                                                                                                difftable[i]:=(i+1)*SpinEdit11.Value;
                                                                                                                difftable[tmp-1-i]:=-(i+1)*SpinEdit11.Value;
                                                                                                                end;

                                                            end;
If radiobutton17.Checked then begin
                              tmp:=Trunc(Power(2,SpinEdit6.Value));
                              diff_used:=tmp;
                              for i:=0 to diff_used-1 do difftable[i]:=i-trunc(tmp/2);
                              end;
If (radiobutton19.Checked) and (radiobutton18.checked) then begin
                              tmp:=Trunc(Power(2,SpinEdit7.Value));
                              diff_used:=tmp;
                              tmp:=0;
                              for i:=0 to 511 do if differences[i]>=threshold then begin
                                                                                   difftable[tmp]:=i-255;
                                                                                   tmp:=tmp+1;
                                                                                   end;
                              end;
If (radiobutton20.Checked) and (radiobutton18.checked) then begin
                              diff_used:=needed;
                              tmp:=0;
                              for i:=0 to 511 do if differences[i]>=SpinEdit8.Value then begin
                                                                                         difftable[tmp]:=i-255;
                                                                                         tmp:=tmp+1;
                                                                                         end;
                              end;
If (radiobutton18.Checked) and (radiobutton33.checked) then begin
                                                            //j=max k=min
                                                            i:=255;
                                                            Repeat
                                                             j:=i;
                                                             i:=i+1;
                                                            Until (differences[i]<100) or (i=511);
                                                            i:=254;
                                                            Repeat
                                                             k:=i;
                                                             i:=i-1;
                                                            Until (differences[i]<100) or (i=0);
                                                            If (j-k)<=Power(2,SpinEdit12.Value) then begin
                                                                                                     tmpr:=ln(j-k)/ln(2);
                                                                                                     If Trunc(tmpr)<>tmpr then tmp:=Trunc(tmpr)+1
                                                                                                                          else tmp:=Trunc(tmpr);
                                                                                                     diff_used:=Trunc(Power(2,tmp));
                                                                                                     needed:=tmp;
                                                                                                     For i:=k to j do begin
                                                                                                                      difftable[i-k]:=i-255;
                                                                                                                      end;
                                                                                                     end
                                                                                                    else begin
                                                                                                         tmp:=Round((j-k)/(Power(2,SpinEdit12.Value)/2+1));
                                                                                                         diff:=Round((j-255)-(j-k)/2);
                                                                                                         diff_used:=Round(Power(2,SpinEdit12.Value));
                                                                                                         needed:=SpinEdit12.Value;
                                                                                                         For i:=0 to Round(Power(2,SpinEdit12.Value)/2)-1 do begin
                                                                                                                                                             difftable[i]:=diff+(i+1)*tmp;
                                                                                                                                                             difftable[diff_used-1-i]:=diff-(i+1)*tmp;
                                                                                                                                                             end;
                                                                                                         end;
                                                            end;
                             

//Перекидываем в чистое изображение на второй вкладке...
Image1.Picture.SaveToFile(ExtractFileDir(Application.ExeName)+'\Pictures\tmp.bmp');
Image2.Picture.LoadFromFile(ExtractFileDir(Application.ExeName)+'\Pictures\tmp.bmp');
Image2.AutoSize:=True;
//Статистика потока данных
//Label20.Caption:=IntToStr(Trunc(FileSizeByName(ExtractFileDir(Application.ExeName)+'\Pictures\tmp.bmp')/1024))+' кбайт';
//Label21.Caption:=IntToStr(Trunc(FileSizeByName(ExtractFileDir(Application.ExeName)+'\Pictures\tmp.bmp')/17))+' кбайт';
Label20.Caption:=IntToStr(Trunc((8*Image2.Width*Image2.Height)/2730.6666))+' кбайт';
Label21.Caption:=IntToStr(Trunc((8*Image2.Width*Image2.Height)/90.6666))+' кбайт';
If RadioButton17.Checked then begin
                              Label22.Caption:=IntToStr(Trunc((SpinEdit6.Value*Image2.Width*Image2.Height)/2730.6666))+' кбайт';
                              Label23.Caption:=IntToStr(Trunc((SpinEdit6.Value*Image2.Width*Image2.Height)/90.6666))+' кбайт';
                              end;
If radiobutton30.Checked then begin
                              Label22.Caption:=IntToStr(Trunc((SpinEdit10.Value*Image2.Width*Image2.Height)/2730.6666))+' кбайт';
                              Label23.Caption:=IntToStr(Trunc((SpinEdit10.Value*Image2.Width*Image2.Height)/90.6666))+' кбайт';
                              end;

If (radiobutton19.Checked) and (radiobutton18.checked) then begin
                                                            Label22.Caption:=IntToStr(Trunc((SpinEdit7.Value*Image2.Width*Image2.Height)/2730.6666))+' кбайт';
                                                            Label23.Caption:=IntToStr(Trunc((SpinEdit7.Value*Image2.Width*Image2.Height)/90.6666))+' кбайт';
                                                            end;
If (radiobutton20.Checked) and (radiobutton18.checked) then begin
                                                            Label22.Caption:=IntToStr(Trunc((needed*Image2.Width*Image2.Height)/2730.6666))+' кбайт';
                                                            Label23.Caption:=IntToStr(Trunc((needed*Image2.Width*Image2.Height)/90.6666))+' кбайт';
                                                            end;
If (Radiobutton33.Checked) and (radiobutton18.Checked) then begin
                                                            Label22.Caption:=IntToStr(Trunc((needed*Image2.Width*Image2.Height)/2730.6666))+' кбайт';
                                                            Label23.Caption:=IntToStr(Trunc((needed*Image2.Width*Image2.Height)/90.6666))+' кбайт';
                                                            end;
//Кодируем
For i:=0 to Image2.Height-1 do begin
                             currclr:=Image2.Picture.Bitmap.Canvas.Pixels[0,i];
                             pr := currclr and $FF;
                             pg := (currclr shr 8) and $FF;
                             pb := (currclr shr 16) and $FF;
                             Reds[i,0]:=pr;
                             Greens[i,0]:=pg;
                             Blues[i,0]:=pb;
                             For j:=1 to Image2.Width-1 do begin
                                                         currclr:=Image2.Picture.Bitmap.Canvas.Pixels[j,i];
                                                         {If j=Trunc(2*Image2.Width/3) then begin
                                                                                           Label13.Caption:='Woah';
                                                                                           end;}
                                                         r := currclr and $FF;
                                                         g := (currclr shr 8) and $FF;
                                                         b := (currclr shr 16) and $FF;
                                                         diff:=r-pr;
                                                         {Reds[i,j]:=diff;
                                                         pr:=pr+Reds[i,j];}
                                                         Reds[i,j]:=FindClosestDiff(diff);
                                                         pr:=pr+DiffTable[Reds[i,j]];
                                                         diff:=b-pb;
                                                         {Blues[i,j]:=diff;
                                                         pb:=pb+Blues[i,j];}
                                                         Blues[i,j]:=FindClosestDiff(diff);
                                                         pb:=pb+DiffTable[Blues[i,j]];
                                                         diff:=g-pg;
                                                         {Greens[i,j]:=diff;
                                                         pg:=pg+Greens[i,j];}
                                                         Greens[i,j]:=FindClosestDiff(diff);
                                                         pg:=pg+DiffTable[Greens[i,j]];
                                                         end;
                             end;
//вносим шумы
If RadioButton14.Checked=False then begin
                                    For k:=1 to Trunc(width*height/SpinEdit3.Value) do begin
                                                                                       i:=random(Height);
                                                                                       j:=random(width);
                                                                                       tmp:=random(3);
                                                                                       //равномерный шум

                                                                                       If tmp=0 then begin
                                                                                                     //генерим шумовое искажение
                                                                                                     If RadioButton15.Checked then tmp:=SpinEdit4.Value-Trunc(SpinEdit5.Value/2)+Random(SpinEdit5.Value)
                                                                                                                              else tmp:=Round(SpinEdit4.Value-SpinEdit5.Value/2)+Round((Random(SpinEdit5.Value)+Random(Spinedit5.Value)+Random(Spinedit5.Value))/3);
                                                                                                     Reds[i,j]:=Reds[i,j]+tmp;
                                                                                                     If Reds[i,j]<0 then Reds[i,j]:=0;
                                                                                                     If Reds[i,j]>diff_used-1 then Reds[i,j]:=diff_used-1;
                                                                                                     end;
                                                                                       If tmp=1 then begin
                                                                                                     //генерим шумовое искажение
                                                                                                     If RadioButton15.Checked then tmp:=SpinEdit4.Value-Trunc(SpinEdit5.Value/2)+Random(SpinEdit5.Value)
                                                                                                                              else tmp:=Round(SpinEdit4.Value-SpinEdit5.Value/2)+Round((Random(SpinEdit5.Value)+Random(Spinedit5.Value)+Random(Spinedit5.Value))/3);
                                                                                                     Greens[i,j]:=Greens[i,j]+tmp;
                                                                                                     If Greens[i,j]<0 then Greens[i,j]:=0;
                                                                                                     If Greens[i,j]>diff_used-1 then Greens[i,j]:=diff_used-1;
                                                                                                     end;
                                                                                       If tmp=2 then begin
                                                                                                     //генерим шумовое искажение
                                                                                                     If RadioButton15.Checked then tmp:=SpinEdit4.Value-Trunc(SpinEdit5.Value/2)+Random(SpinEdit5.Value)
                                                                                                                              else tmp:=Round(SpinEdit4.Value-SpinEdit5.Value/2)+Round((Random(SpinEdit5.Value)+Random(Spinedit5.Value)+Random(Spinedit5.Value))/3);
                                                                                                     Blues[i,j]:=Blues[i,j]+tmp;
                                                                                                     If Blues[i,j]<0 then Blues[i,j]:=0;
                                                                                                     If Blues[i,j]>diff_used-1 then Blues[i,j]:=diff_used-1;
                                                                                                     end;
                                                                                       end;

                                    end;
//декодируем                             
Bitmap.Width:=Image2.width;
Bitmap.Height:=Image2.Height;
For i:=0 to Bitmap.Height-1 do begin
                               //первый пиксель из значений
                               currclr:=Reds[i,0]+Greens[i,0]*256+Blues[i,0]*256*256;
                               {Image3.Picture.}Bitmap.Canvas.Pixels[0,i]:=currclr;
                               pr := Reds[i,0];
                               pg := Greens[i,0];
                               pb := Blues[i,0];
                               For j:=1 to Bitmap.Width-1 do begin
                                                             r:=pr+DiffTable[Reds[i,j]];
                                                             g:=pg+DiffTable[Greens[i,j]];
                                                             b:=pb+DiffTable[Blues[i,j]];
                                                             {r:=pr+Reds[i,j];
                                                             g:=pg+Greens[i,j];
                                                             b:=pb+Blues[i,j];}
                                                             currclr:=r+256*g+256*256*b;
                                                             Bitmap.Canvas.Pixels[j,i]:=currclr;
                                                             pr:=r;
                                                             pb:=b;
                                                             pg:=g;
                                                             end;
                               end;
Bitmap.SaveToFile(ExtractFileDir(Application.ExeName)+'\Pictures\Result.bmp');
Image3.Picture.LoadFromFile(ExtractFileDir(Application.ExeName)+'\Pictures\Result.bmp');
Image2.AutoSize:=True;
Image3.AutoSize:=True;
RadioButton21.Checked:=True;
RadioButton21Click(Self);
//формируем цветоразностное изображение
tmp:=0;
diff:=0;
For i:=0 to Image2.Height-1 do
For j:=0 to Image2.Width-1 do begin
                              Bitmap.Canvas.Pixels[j,i]:=Image2.Picture.Bitmap.Canvas.Pixels[j,i]-Image3.Picture.Bitmap.Canvas.Pixels[j,i]+16777215;
                              currclr:=Image2.Picture.Bitmap.Canvas.Pixels[j,i]-Image3.Picture.Bitmap.Canvas.Pixels[j,i];
                              if currclr<>0 then begin
                                                 tmp:=tmp+1;
                                                 diff :=diff + (currclr and $FF) + ((currclr shr 8) and $FF) + ((currclr shr 16) and $FF);
                                                 end;
                              end;
Bitmap.SaveToFile(ExtractFileDir(Application.ExeName)+'\Pictures\tmp.bmp');
Image4.Picture.LoadFromFile(ExtractFileDir(Application.ExeName)+'\Pictures\tmp.bmp');
Label25.Caption:=IntToStr(Round(tmp/(Image2.Width*Image2.Height)*100))+'%';
Label27.Caption:=IntToStr((Round(diff/(Image2.Width*Image2.Height*765)*100)))+'%';
Bitmap.Destroy;
Combobox2.Items.Clear;
Combobox2.Items.Add('Распределение значений цветовых отсчетов');
Combobox2.Items.Add('Распределение разностей цветовых отсчетов');
Combobox2.Items.Add('Отклонение от среднего значения');
Combobox2.Items.Add('');
Chart3.Series[0].Clear;
Application.MessageBox('Кодирование и декодирование завершено.','Сообщение',mb_ok);
PageSourceControl1.ActivePageIndex:=1;
end;

procedure TForm1.RadioButton21Click(Sender: TObject);
begin
If RadioButton21.Checked then begin
                              Image2.Visible:=True;
                              Image3.Visible:=False;
                              Image4.Visible:=False;
                              end;
end;

procedure TForm1.RadioButton22Click(Sender: TObject);
begin
If RadioButton22.Checked then begin
                              Image2.Visible:=False;
                              Image3.Visible:=True;
                              Image4.Visible:=False;
                              end;
end;

procedure TForm1.RadioButton23Click(Sender: TObject);
begin
If RadioButton23.Checked then begin
                              Image2.Visible:=False;
                              Image3.Visible:=False;
                              Image4.Visible:=True;
                              end;
end;

procedure TForm1.RadioButton24Click(Sender: TObject);
var
i,j:Integer;
arr:array[-255..255] of Integer;
currclr,prevclr:Integer;
begin
For i:=-255 to 255 do arr[i]:=0;
Chart3.Series[0].Clear;
If ComboBox2.Text='Распределение значений цветовых отсчетов' then begin
                                                                  Chart3.Title.Text.Clear;
                                                                  Chart3.Title.Text.Add('Распределение значений цветовых отсчетов в исходном изображении');
                                                                  For i:=0 to Image2.Height-1 do
                                                                  For j:=0 to Image2.Width-1 do begin
                                                                                                currclr:=Image2.Picture.Bitmap.Canvas.Pixels[j,i];
                                                                                                arr[(currclr and $FF)]:=arr[(currclr and $FF)]+1;
                                                                                                arr[((currclr shr 8) and $FF)]:=arr[((currclr shr 8) and $FF)]+1;
                                                                                                arr[((currclr shr 16) and $FF)]:=arr[((currclr shr 16) and $FF)]+1;
                                                                                                end;
                                                                  For i:=-255 to 255 do Chart3.Series[0].AddXY(i,Round(arr[i]/3));
                                                                  end;
If ComboBox2.Text='Распределение разностей цветовых отсчетов' then begin
                                                                   Chart3.Title.Text.Clear;
                                                                   Chart3.Title.Text.Add('Распределение разностей значений цветовых отсчетов в исходном изображении');
                                                                   For i:=0 to Image2.Height-1 do
                                                                   For j:=1 to Image2.Width-1 do begin
                                                                                                currclr:=Image2.Picture.Bitmap.Canvas.Pixels[j,i];
                                                                                                prevclr:=Image2.Picture.Bitmap.Canvas.Pixels[j-1,i];
                                                                                                arr[(currclr and $FF)-(prevclr and $FF)]:=arr[(currclr and $FF)-(prevclr and $FF)]+1;
                                                                                                arr[((currclr shr 8) and $FF)-((prevclr shr 8) and $FF)]:=arr[((currclr shr 8) and $FF)-((prevclr shr 8) and $FF)]+1;
                                                                                                arr[((currclr shr 16) and $FF)-((prevclr shr 16) and $FF)]:=arr[((currclr shr 16) and $FF)-((prevclr shr 16) and $FF)]+1;
                                                                                                end;
                                                                   For i:=-255 to 255 do Chart3.Series[0].AddXY(i,Round(arr[i]/3));
                                                                   end;
If ComboBox2.Text='Отклонение от среднего значения' then begin
                                                         Chart3.Title.Text.Clear;
                                                         Chart3.Title.Text.Add('Отклонение значений цветовых отсчетов от среднего значения в исходном изображении');
                                                         prevclr:=0;
                                                         For i:=0 to Image2.Height-1 do
                                                         For j:=0 to Image2.Width-1 do begin
                                                                                       currclr:=Image2.Picture.Bitmap.Canvas.Pixels[j,i];
                                                                                       prevclr:=prevclr+(currclr and $FF) + ((currclr shr 8) and $FF) + ((currclr shr 16) and $FF);
                                                                                       end;
                                                         prevclr:=Round(prevclr/Image2.Height/Image2.Width/3);
                                                         For i:=0 to Image2.Height-1 do
                                                         For j:=0 to Image2.Width-1 do begin
                                                                                       currclr:=Image2.Picture.Bitmap.Canvas.Pixels[j,i];
                                                                                       arr[(currclr and $FF)-prevclr]:=arr[(currclr and $FF)-prevclr]+1;
                                                                                       arr[((currclr shr 8) and $FF)-prevclr]:=arr[((currclr shr 8) and $FF)-prevclr]+1;
                                                                                       arr[((currclr shr 16) and $FF)-prevclr]:=arr[((currclr shr 16) and $FF)-prevclr]+1;
                                                                                       end;
                                                         For i:=-255 to 255 do Chart3.Series[0].AddXY(i,Round(arr[i]/3));
                                                         end;
end;

procedure TForm1.RadioButton25Click(Sender: TObject);
var
i,j:Integer;
arr:array[-255..255] of Integer;
currclr,prevclr:Integer;
begin
For i:=-255 to 255 do arr[i]:=0;
Chart3.Series[0].Clear;
If ComboBox2.Text='Распределение значений цветовых отсчетов' then begin
                                                                  Chart3.Title.Text.Clear;
                                                                  Chart3.Title.Text.Add('Распределение значений цветовых отсчетов в изображении после преобразования');
                                                                  For i:=0 to Image3.Height-1 do
                                                                  For j:=0 to Image3.Width-1 do begin
                                                                                                currclr:=Image3.Picture.Bitmap.Canvas.Pixels[j,i];
                                                                                                arr[(currclr and $FF)]:=arr[(currclr and $FF)]+1;
                                                                                                arr[((currclr shr 8) and $FF)]:=arr[((currclr shr 8) and $FF)]+1;
                                                                                                arr[((currclr shr 16) and $FF)]:=arr[((currclr shr 16) and $FF)]+1;
                                                                                                end;
                                                                  For i:=-255 to 255 do Chart3.Series[0].AddXY(i,Round(arr[i]/3));
                                                                  end;
If ComboBox2.Text='Распределение разностей цветовых отсчетов' then begin
                                                                   Chart3.Title.Text.Clear;
                                                                   Chart3.Title.Text.Add('Распределение разностей значений цветовых отсчетов в изображении после преобразования');
                                                                   For i:=0 to Image3.Height-1 do
                                                                   For j:=1 to Image3.Width-1 do begin
                                                                                                currclr:=Image3.Picture.Bitmap.Canvas.Pixels[j,i];
                                                                                                prevclr:=Image3.Picture.Bitmap.Canvas.Pixels[j-1,i];
                                                                                                arr[(currclr and $FF)-(prevclr and $FF)]:=arr[(currclr and $FF)-(prevclr and $FF)]+1;
                                                                                                arr[((currclr shr 8) and $FF)-((prevclr shr 8) and $FF)]:=arr[((currclr shr 8) and $FF)-((prevclr shr 8) and $FF)]+1;
                                                                                                arr[((currclr shr 16) and $FF)-((prevclr shr 16) and $FF)]:=arr[((currclr shr 16) and $FF)-((prevclr shr 16) and $FF)]+1;
                                                                                                end;
                                                                   For i:=-255 to 255 do Chart3.Series[0].AddXY(i,Round(arr[i]/3));
                                                                   end;
If ComboBox2.Text='Отклонение от среднего значения' then begin
                                                         Chart3.Title.Text.Clear;
                                                         Chart3.Title.Text.Add('Отклонение значений цветовых отсчетов от среднего значения в изображении после преобразования');
                                                         prevclr:=0;
                                                         For i:=0 to Image3.Height-1 do
                                                         For j:=0 to Image3.Width-1 do begin
                                                                                       currclr:=Image3.Picture.Bitmap.Canvas.Pixels[j,i];
                                                                                       prevclr:=prevclr+(currclr and $FF) + ((currclr shr 8) and $FF) + ((currclr shr 16) and $FF);
                                                                                       end;
                                                         prevclr:=Round(prevclr/Image3.Height/Image3.Width/3);
                                                         For i:=0 to Image3.Height-1 do
                                                         For j:=0 to Image3.Width-1 do begin
                                                                                       currclr:=Image3.Picture.Bitmap.Canvas.Pixels[j,i];
                                                                                       arr[(currclr and $FF)-prevclr]:=arr[(currclr and $FF)-prevclr]+1;
                                                                                       arr[((currclr shr 8) and $FF)-prevclr]:=arr[((currclr shr 8) and $FF)-prevclr]+1;
                                                                                       arr[((currclr shr 16) and $FF)-prevclr]:=arr[((currclr shr 16) and $FF)-prevclr]+1;
                                                                                       end;
                                                         For i:=-255 to 255 do Chart3.Series[0].AddXY(i,Round(arr[i]/3));
                                                         end;
end;

procedure TForm1.ComboBox2Change(Sender: TObject);
begin
If Radiobutton24.Checked then RadioButton24Click(Self);
If Radiobutton25.Checked then RadioButton25Click(Self);
end;

procedure TForm1.RadioButton29Click(Sender: TObject);
begin
DefaultDropped(0,false);
StringGrid1.Enabled:=False;
SpinEdit9.Enabled:=True;
StringGrid1.FixedCols:=7;
StringGrid1.FixedRows:=7;     
end;

procedure TForm1.RadioButton28Click(Sender: TObject);
begin
SpinEdit9.Enabled:=False;
StringGrid1.Enabled:=True;
If RadioButton26.Checked then RadioButton26Click(Self);
If RadioButton27.Checked then RadioButton27Click(Self);
end;

procedure TForm1.RadioButton26Click(Sender: TObject);
begin
StringGrid1.FixedCols:=4;
StringGrid1.FixedRows:=4;
StringGrid1.Enabled:=True;
DefaultDropped(4,true);
end;

procedure TForm1.RadioButton27Click(Sender: TObject);
begin
StringGrid1.FixedCols:=0;
StringGrid1.FixedRows:=0;
StringGrid1.Enabled:=True;
DefaultDropped(8,false);
end;

procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
  Rect: TRect; State: TGridDrawState);
begin
if dropped[ACol,ARow]=1 then StringGrid1.Canvas.Brush.color := clBlack
                        else StringGrid1.canvas.brush.Color := clWhite;
StringGrid1.canvas.fillRect(Rect);
end;

procedure TForm1.StringGrid1SelectCell(Sender: TObject; ACol,
  ARow: Integer; var CanSelect: Boolean);
begin
if dropped[Acol,Arow]=1 then dropped[Acol,Arow]:=0
                        else dropped[Acol,Arow]:=1;
end;

procedure TForm1.Image2Click(Sender: TObject);
begin
Image2.Picture.SaveToFile(ExtractFileDir(Application.ExeName)+'\Pictures\tmp.bmp');
Form2.Image1.Picture.LoadFromFile(ExtractFileDir(Application.ExeName)+'\Pictures\tmp.bmp');
If Image2.width/Image2.height<4/3 then begin
                  Form2.Image1.width:=Screen.Width;
                  Form2.Image1.height:=Round(Screen.Width/(Image2.width/Image2.height));
                  end
             else begin
                  Form2.Image1.height:=Screen.Height;
                  Form2.Image1.width:=Round((Image2.width/Image2.height)*Screen.Height);
                  end;
Form2.AutoSize:=True;
Form2.Show;
end;

procedure TForm1.Image3Click(Sender: TObject);
begin
Image3.Picture.SaveToFile(ExtractFileDir(Application.ExeName)+'\Pictures\tmp.bmp');
Form2.Image1.Picture.LoadFromFile(ExtractFileDir(Application.ExeName)+'\Pictures\tmp.bmp');
If Image3.width/Image3.height<4/3 then begin
                  Form2.Image1.width:=Screen.Width;
                  Form2.Image1.height:=Round(Screen.Width/(Image3.width/Image3.height));
                  end
             else begin
                  Form2.Image1.height:=Screen.Height;
                  Form2.Image1.width:=Round((Image3.width/Image3.height)*Screen.Height);
                  end;
Form2.AutoSize:=True;
Form2.Show;
end;

procedure TForm1.Image4Click(Sender: TObject);
begin
Image4.Picture.SaveToFile(ExtractFileDir(Application.ExeName)+'\Pictures\tmp.bmp');
Form2.Image1.Picture.LoadFromFile(ExtractFileDir(Application.ExeName)+'\Pictures\tmp.bmp');
If Image4.width/Image4.height<4/3 then begin
                  Form2.Image1.width:=Screen.Width;
                  Form2.Image1.height:=Round(Screen.Width/(Image4.width/Image4.height));
                  end
             else begin
                  Form2.Image1.height:=Screen.Height;
                  Form2.Image1.width:=Round((Image4.width/Image4.height)*Screen.Height);
                  end;
Form2.AutoSize:=True;
Form2.Show;
end;

procedure TForm1.Chart2Click(Sender: TObject);
begin
if Chart2.AnimatedZoom then begin
                       Chart2.AnimatedZoom:=False;
                       Chart2.Title.Text.Clear;
                       Chart2.Series[0].Clear;
                       Chart2.Title.Text.Add('Распределение шума (пример). Щелкните, чтобы включить график.');
                       end
                  else begin
                       Chart2.AnimatedZoom:=True;
                       Chart2.Title.Text.Clear;
                       Chart2.Title.Text.Add('Распределение шума (пример).');
                       SpinEdit4Change(Self);
                       end;
end;

procedure TForm1.Chart2ClickAxis(Sender: TCustomChart; Axis: TChartAxis;
  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
 Chart2Click(self);
end;

procedure TForm1.Chart2ClickBackground(Sender: TCustomChart;
  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
Chart2Click(self);
end;

procedure TForm1.Chart2ClickLegend(Sender: TCustomChart;
  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
Chart2Click(self);
end;

procedure TForm1.Chart2ClickSeries(Sender: TCustomChart;
  Series: TChartSeries; ValueIndex: Integer; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
Chart2Click(self);
end;

procedure TForm1.Chart2Enter(Sender: TObject);
begin
Chart2Click(self);
end;

procedure TForm1.Chart2MouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
Chart2Click(self);
end;

procedure TForm1.RadioButton30Click(Sender: TObject);
begin
If RadioButton30.Checked then begin
                              SpinEdit10.Enabled:=True;
                              RadioButton31.Enabled:=True;
                              RadioButton32.Enabled:=True;
                              SpinEdit11.Enabled:=True;
                              SpinEdit6.Enabled:=False;
                              RadioButton19.Enabled:=False;
                              RadioButton20.Enabled:=False;
                              label12.enabled:=False;
                              SpinEdit7.Enabled:=False;
                              SpinEdit8.Enabled:=False;
                              RadioButton33.Enabled:=False;
                              SpinEdit12.Enabled:=False;
                              If RadioButton31.Checked then RadioButton31click(Self)
                                                       else SpinEdit11Change(Self);
                              end;
end;

procedure TForm1.SpinEdit10Change(Sender: TObject);
var
max:Integer;
i,j:Integer;
begin
try
If Radiobutton31.Checked then begin
Chart1.Series[1].Clear;
max:=0;
For i:=0 to 511 do If differences[i]>max then max:=differences[i];
//j:=Round(512/(Power(2,SpinEdit10.Value)));
j:=Round(255/(Power(2,SpinEdit10.Value)/2+1));
For i:=1 to Round(Power(2,SpinEdit10.Value)/2) do begin
                                                  Chart1.Series[1].AddXY(i*j,0);
                                                  Chart1.Series[1].AddXY(i*j,max);
                                                  Chart1.Series[1].AddXY(i*j+1,0);
                                                  Chart1.Series[1].AddXY(-i*j,0);
                                                  Chart1.Series[1].AddXY(-i*j,max);
                                                  Chart1.Series[1].AddXY(-i*j+1,0);
                                                  end;
Label13.Caption:='Пространство разностных отсчетов от -255 до +255 будет равномерно заполнено '+IntToStr(Trunc(Power(2,SpinEdit10.Value)))+' уровнями квантования.'
end
else SpinEdit11Change(Self);
except
end;
end;

procedure TForm1.SpinEdit11Change(Sender: TObject);
var
max:Integer;
i:Integer;
begin
try
Chart1.Series[1].Clear;
max:=0;
For i:=0 to 511 do If differences[i]>max then max:=differences[i];
For i:=1 to Round(Power(2,SpinEdit10.Value)/2) do begin
                                                  Chart1.Series[1].AddXY(i*SpinEdit11.Value,0);
                                                  Chart1.Series[1].AddXY(i*SpinEdit11.Value,max);
                                                  Chart1.Series[1].AddXY(i*SpinEdit11.Value+1,0);
                                                  Chart1.Series[1].AddXY(-i*SpinEdit11.Value,0);
                                                  Chart1.Series[1].AddXY(-i*SpinEdit11.Value,max);
                                                  Chart1.Series[1].AddXY(-i*SpinEdit11.Value+1,0);
                                                  end;
Label13.Caption:='Пространство разностных отсчетов от '+IntToStr(Round(-1*Power(2,SpinEdit10.Value)/2*SpinEdit11.Value))+' до '+IntToStr(Round(Power(2,SpinEdit10.Value)/2*SpinEdit11.Value))+' будет заполнено '+IntToStr(Trunc(Power(2,SpinEdit10.Value)))+' уровнями квантования с шагом '+IntToStr(SpinEdit11.Value)+'.';
except
end;
end;

procedure TForm1.RadioButton31Click(Sender: TObject);
begin
SpinEdit10Change(Self);
end;

procedure TForm1.RadioButton32Click(Sender: TObject);
begin
SpinEdit11Change(Self);
end;

procedure TForm1.RadioButton33Click(Sender: TObject);
begin
If (RadioButton33.Checked) and (RadioButton18.Checked) then begin
                                                            SpinEdit7.Enabled:=False;
                                                            SpinEdit8.Enabled:=False;
                                                            SpinEdit12.Enabled:=True;
                                                            SpinEdit12Change(Self);
                                                            end;
end;

procedure TForm1.SpinEdit12Change(Sender: TObject);
var
i,j:Integer;
min,max:Integer;
tmp:Real;
resultn:Integer;
begin
Chart1.Series[1].Clear;
i:=255;
Repeat
 max:=i;
 i:=i+1;
Until (differences[i]<100) or (i=511);
i:=254;
Repeat
 min:=i;
 i:=i-1;
Until (differences[i]<100) or (i=0);
If (max-min)<=Power(2,SpinEdit12.Value) then begin
                                             Chart1.Series[1].AddXY(min-255,0);
                                             Chart1.Series[1].AddXy(max-255,0);
                                             For i:=min to max do Chart1.Series[1].AddXY(i-255,differences[i]);
                                             tmp:=ln(max-min)/ln(2);
                                             If Trunc(tmp)<>tmp then resultn:=Trunc(tmp)+1
                                                                else resultn:=Trunc(tmp);
                                             Label13.Caption:='Центральный максимум от '+IntToStr(min-255)+' до '+IntToStr(max-255)+' будет заполнен '+IntToStr(max-min)+' уровнями квантования с шагом 1.'+#10+#13+'Для этого потребуется '+IntToStr(resultn)+' бит на отсчет.';
                                             end
                                        else begin
                                             Chart1.Series[1].AddXY(min,0);
                                             Chart1.Series[1].AddXy(max,0);
                                             j:=Round((max-min)/(Power(2,SpinEdit12.Value)/2+1));
                                             resultn:=Round((max-255)-(max-min)/2);
                                             For i:=1 to Round(Power(2,SpinEdit10.Value)/2) do begin
                                                                                               Chart1.Series[1].AddXY(resultn+i*j,0);
                                                                                               Chart1.Series[1].AddXY(resultn+i*j,differences[resultn+i*j+255]);
                                                                                               Chart1.Series[1].AddXY(resultn+i*j+1,0);
                                                                                               Chart1.Series[1].AddXY(resultn-i*j,0);
                                                                                               Chart1.Series[1].AddXY(resultn-i*j,differences[resultn-i*j+255]);
                                                                                               Chart1.Series[1].AddXY(resultn-i*j+1,0);
                                                                                               end;
                                             resultn:=Round(Power(2,SpinEdit12.Value));
                                             Label13.Caption:='Центральный максимум от '+IntToStr(min-255)+' до '+IntToStr(max-255)+' будет заполнен '+IntToStr(resultn)+' уровнями квантования с шагом '+IntToStr(j)+'.'
                                             end;
end;

procedure TForm1.Button4Click(Sender: TObject);
var
width_steps, height_steps, size:Integer;
tmp:real;
i,j:Integer;
current_fragment_horizontal, current_fragment_vertical:Integer;
current_element_horizontal, current_element_vertical:Integer;
H:array [0..7,0..7] of Integer;
r,g,b:Byte;
currclr:TColor;
Bitmap:TBitmap;
begin
Image5.Picture.SaveToFile(ExtractFileDir(Application.ExeName)+'\Pictures\tmp.bmp');
Image2.Picture.LoadFromFile(ExtractFileDir(Application.ExeName)+'\Pictures\tmp.bmp');
Image2.AutoSize:=True;
Bitmap:=TBitmap.Create;
Bitmap.Height:=Image2.Height;
Bitmap.Width:=Image2.Width;
For i:=0 to Bitmap.Height-1 do
For j:=0 to Bitmap.Width-1 do Bitmap.Canvas.Pixels[j,i]:=0;
// Определяем количество фрагментов 4х4 или 8х8 в изображении
If RadioButton26.Checked then size:=4
                         else size:=8;
tmp:=Image2.Height/size;
If trunc(tmp)=tmp then height_steps:=trunc(tmp)
                  else height_steps:=trunc(tmp)+1;
tmp:=Image2.Width/size;
If trunc(tmp)=tmp then width_steps:=trunc(tmp)
                  else width_steps:=trunc(tmp)+1;
//Загружаем базисные изображения преобразования адамара.
//AdamarImages - массив этих изображений. По адресу [x,y] в нем хранится матрица отсчетов, соответствующая базисному изображению phiXY.
//В ней, аналогично, хранятся коэффициенты 1 и -1.
For i:=0 to size-1 do
For j:=0 to size-1 do LoadAdamarBasisImage(size,i,j);
//Кодируем
//Проходим изображение, забирая фрагменты заданного размера...
For current_fragment_vertical:=0 to height_steps-1 do
For current_fragment_horizontal:=0 to width_steps-1 do begin
                                                       //Проходим все элементы фрагмента, умножая их на базисные изображения
                                                       For current_element_vertical:=0 to size-1 do
                                                       For current_element_horizontal:=0 to size-1 do begin
                                                                                                      {currclr:=Image2.Picture.Bitmap.Canvas.Pixels[current_fragment_horizontal*size+current_element_horizontal,current_fragment_vertical*size+current_element_vertical];
                                                                                                      r := currclr and $FF;          (Image2.Picture.Bitmap.Canvas.Pixels[current_fragment_horizontal*size+i,current_fragment_vertical*size+j] and $FF)
                                                                                                      g := (currclr shr 8) and $FF;  ((Image2.Picture.Bitmap.Canvas.Pixels[current_fragment_horizontal*size+i,current_fragment_vertical*size+j] shr 8) and $FF)
                                                                                                      b := (currclr shr 16) and $FF; ((Image2.Picture.Bitmap.Canvas.Pixels[current_fragment_horizontal*size+i,current_fragment_vertical*size+j] shr 16) and $FF)}
                                                                                                      //кодируем красный
                                                                                                      //Обнуляем матрицу H 
                                                                                                      H[current_element_horizontal,current_element_vertical]:=0;
                                                                                                      For i:=0 to size-1 do 
                                                                                                      For j:=0 to size-1 do H[current_element_horizontal,current_element_vertical]:=H[current_element_horizontal,current_element_vertical]+(Image2.Picture.Bitmap.Canvas.Pixels[current_fragment_horizontal*size+i,current_fragment_vertical*size+j] and $FF)*AdamarImages[current_element_horizontal,current_element_vertical].Values[i,j];
                                                                                                      H[current_element_horizontal,current_element_vertical]:=Round(H[current_element_horizontal,current_element_vertical]/size/size);
                                                                                                      Reds[current_fragment_vertical*size+current_element_vertical,current_fragment_horizontal*size+current_element_horizontal]:=H[current_element_horizontal,current_element_vertical];
                                                                                                      //Кодируем синий
                                                                                                      H[current_element_horizontal,current_element_vertical]:=0;
                                                                                                      For i:=0 to size-1 do 
                                                                                                      For j:=0 to size-1 do H[current_element_horizontal,current_element_vertical]:=H[current_element_horizontal,current_element_vertical]+((Image2.Picture.Bitmap.Canvas.Pixels[current_fragment_horizontal*size+i,current_fragment_vertical*size+j] shr 16) and $FF)*AdamarImages[current_element_horizontal,current_element_vertical].Values[i,j];
                                                                                                      H[current_element_horizontal,current_element_vertical]:=Round(H[current_element_horizontal,current_element_vertical]/size/size);
                                                                                                      Blues[current_fragment_vertical*size+current_element_vertical,current_fragment_horizontal*size+current_element_horizontal]:=H[current_element_horizontal,current_element_vertical];
                                                                                                      //кодируем зеленый
                                                                                                      H[current_element_horizontal,current_element_vertical]:=0;
                                                                                                      For i:=0 to size-1 do 
                                                                                                      For j:=0 to size-1 do H[current_element_horizontal,current_element_vertical]:=H[current_element_horizontal,current_element_vertical]+((Image2.Picture.Bitmap.Canvas.Pixels[current_fragment_horizontal*size+i,current_fragment_vertical*size+j] shr 8) and $FF)*AdamarImages[current_element_horizontal,current_element_vertical].Values[i,j];
                                                                                                      H[current_element_horizontal,current_element_vertical]:=Round(H[current_element_horizontal,current_element_vertical]/size/size);
                                                                                                      Greens[current_fragment_vertical*size+current_element_vertical,current_fragment_horizontal*size+current_element_horizontal]:=H[current_element_horizontal,current_element_vertical];
                                                                                                      end;  
                                                       end;
//декодируем
For current_fragment_vertical:=0 to height_steps-1 do
For current_fragment_horizontal:=0 to width_steps-1 do begin                                                       
                                                       For i:=0 to size-1 do 
                                                       For j:=0 to size-1 do H[i,j]:=0;
                                                       //декодирование красного
                                                       For current_element_vertical:=0 to size-1 do
                                                       For current_element_horizontal:=0 to size-1 do begin
                                                                                                      For i:=0 to size-1 do
                                                                                                      For j:=0 to size-1 do H[current_element_horizontal,current_element_vertical]:=H[current_element_horizontal,current_element_vertical]+Reds[current_fragment_vertical*size+current_element_vertical,current_fragment_horizontal*size+current_element_vertical]*AdamarImages[i,j].Values[current_element_horizontal,current_element_vertical];
                                                                                                      Bitmap.Canvas.Pixels[current_fragment_horizontal*size+current_element_horizontal,current_fragment_vertical*size+current_element_vertical]:=Image3.Picture.Bitmap.Canvas.Pixels[current_fragment_horizontal*size+current_element_horizontal,current_fragment_vertical*size+current_element_vertical]+Round(H[current_element_horizontal,current_element_vertical]/64);
                                                                                                      end;
                                                       For i:=0 to size-1 do 
                                                       For j:=0 to size-1 do H[i,j]:=0;
                                                       //декодирование зеленого
                                                       For current_element_vertical:=0 to size-1 do
                                                       For current_element_horizontal:=0 to size-1 do begin
                                                                                                      For i:=0 to size-1 do
                                                                                                      For j:=0 to size-1 do H[current_element_horizontal,current_element_vertical]:=H[current_element_horizontal,current_element_vertical]+Greens[current_fragment_vertical*size+current_element_vertical,current_fragment_horizontal*size+current_element_vertical]*AdamarImages[i,j].Values[current_element_horizontal,current_element_vertical];
                                                                                                      Bitmap.Canvas.Pixels[current_fragment_horizontal*size+current_element_horizontal,current_fragment_vertical*size+current_element_vertical]:=Image3.Picture.Bitmap.Canvas.Pixels[current_fragment_horizontal*size+current_element_horizontal,current_fragment_vertical*size+current_element_vertical]+Round(H[current_element_horizontal,current_element_vertical]*256/64);
                                                                                                      end;
                                                       For i:=0 to size-1 do 
                                                       For j:=0 to size-1 do H[i,j]:=0;
                                                       //декодирование синего
                                                       For current_element_vertical:=0 to size-1 do
                                                       For current_element_horizontal:=0 to size-1 do begin
                                                                                                      For i:=0 to size-1 do
                                                                                                      For j:=0 to size-1 do H[current_element_horizontal,current_element_vertical]:=H[current_element_horizontal,current_element_vertical]+Blues[current_fragment_vertical*size+current_element_vertical,current_fragment_horizontal*size+current_element_vertical]*AdamarImages[i,j].Values[current_element_horizontal,current_element_vertical];
                                                                                                      Bitmap.Canvas.Pixels[current_fragment_horizontal*size+current_element_horizontal,current_fragment_vertical*size+current_element_vertical]:=Image3.Picture.Bitmap.Canvas.Pixels[current_fragment_horizontal*size+current_element_horizontal,current_fragment_vertical*size+current_element_vertical]+Round(H[current_element_horizontal,current_element_vertical]*256*256/64);
                                                                                                      end;
                                                       end;
Bitmap.SaveToFile(ExtractFileDir(Application.ExeName)+'\Pictures\tmp.bmp');
Image3.Picture.LoadFromFile(ExtractFileDir(Application.ExeName)+'\Pictures\tmp.bmp');
Image3.AutoSize:=True;
Bitmap.Destroy;
Application.MessageBox('Кодирование и декодирование завершено.','Сообщение',mb_ok);

end;

procedure TForm1.Button5Click(Sender: TObject);
begin
If OpenDialog2.Execute then begin
                            Button6.Enabled:=True;
                            Edit2.Text:=OpenDialog2.FileName;
                            Edit2.Enabled:=True;
                            FilterGraph.Stop;
                            FilterGraph.ClearGraph;
                            Button8.Enabled:=False;
                            end;
end;

procedure TForm1.Button6Click(Sender: TObject);
var
tmpstr:String;
i:Integer;
begin

GroupBox12.Visible:=True;
GroupBox5.Visible:=True;
GroupBox13.Visible:=True;

//Получаем информацию о доступных энкодерах
tmpstr:=ExtractFileDir(Application.ExeName)+'\ffmpeg\ffprobe -encoders'+' 1>'+#34+ExtractFileDir(Application.ExeName)+'\ffmpeg\tmp.txt'+#34+' 2>&1';
GetDOSOutPut(tmpstr,ExtractFileDir(Application.ExeName));
tmpstr:=ExtractFileDir(Application.ExeName)+'\ffmpeg\tmp.txt';
Memo1.Lines.LoadFromFile(tmpstr);
DeleteFile(tmpstr);
For i:=1 to Memo1.Lines.Count do begin
                                  If Pos('mpeg2video',Memo1.Lines[i])>0 then RadioButton34.Enabled:=True;
                                  If Pos('mpeg4',Memo1.Lines[i])>0 then RadioButton35.Enabled:=True;
                                  If Pos('libx264',Memo1.Lines[i])>0 then RadioButton36.Enabled:=True;
                                  end;
Memo1.Lines.Clear;
If RadioButton36.Enabled then RadioButton36.Checked:=True;
If RadioButton35.Enabled then RadioButton35.Checked:=True;
If RadioButton34.Enabled then RadioButton34.Checked:=True;
If (RadioButton34.Enabled=False) or (RadioButton35.Enabled=False) or (RadioButton36.Enabled=False) then Application.MessageBox('В системе доступны не все используемые программой кодеки. Пожалуйста, поставьте свежий пакет (в папке программы есть дистрибутив K-Lite).','Ошибка',mb_ok  or MB_ICONERROR);

//Получаем информацию о загруженном файле
Memo1.WordWrap:=False;
tmpstr:=ExtractFileDir(Application.ExeName)+'\ffmpeg\ffprobe -loglevel verbose -pretty -i '+#34+Edit2.Text+#34+' 1>'+#34+ExtractFileDir(Application.ExeName)+'\ffmpeg\tmp.txt'+#34+' 2>&1';
GetDOSOutPut(tmpstr,ExtractFileDir(Application.ExeName));
tmpstr:=ExtractFileDir(Application.ExeName)+'\ffmpeg\tmp.txt';
memo1.lines.add(tmpstr);
Memo1.Lines.LoadFromFile(tmpstr);
Memo1.Lines.Delete(0);
Repeat
Memo1.Lines.Delete(0);
Until (Memo1.Lines[0][1]<>' ') or (Memo1.Lines.Count=0);
Memo1.WordWrap:=True;  

try
if not FilterGraph.Active then FilterGraph.Active := true;
FilterGraph.ClearGraph;
FilterGraph.RenderFile(Edit2.Text);
FilterGraph.Volume:=0;
FilterGraph.Play;
sleep(1000);
If (FilterGraph.State<>gsPlaying) or (FilterGraph.Duration<60) then ToolButton7Click(Self);
except
ToolButton7Click(Self);
end;
Edit2.Enabled:=False;

end;

procedure TForm1.ToolButton1Click(Sender: TObject);
begin
 FilterGraph.Pause;
end;

procedure TForm1.ToolButton3Click(Sender: TObject);
begin
  FilterGraph.Play;
end;

procedure TForm1.ToolButton5Click(Sender: TObject);
var
MediaSeeking: IMediaSeeking;
StopPosition, Position: int64;
begin
FilterGraph.Stop;
FilterGraph.QueryInterface(IMediaSeeking, MediaSeeking);
MediaSeeking.GetStopPosition(StopPosition);
Position := 0;
MediaSeeking.SetPositions(Position, AM_SEEKING_AbsolutePositioning, StopPosition, AM_SEEKING_NoPositioning);
end;

procedure TForm1.ToolButton7Click(Sender: TObject);
var
tmpstr:String;
begin
tmpstr:=ExtractFileDir(Application.ExeName)+'\ffmpeg\ffplay';
ShellExecute(handle,'open',PChar(tmpstr), PChar('-an '+#34+Edit2.Text+#34),'',SW_SHOWNORMAL);
//GetDOSOutput(tmpstr,ExtractFileDir(Edit2.Text));
end;

procedure TForm1.Button7Click(Sender: TObject);
var
tmpstr,tmpstr2:String;
i,j,k,err1:Integer;
bitrate,framerate:Real;
MySystem: TSystemInfo;
begin
GetSystemInfo(MySystem);

tmpstr:=ExtractFileDir(Application.ExeName)+'\ffmpeg\ffmpeg.exe -i '+#34+Edit2.Text+#34+' -mbd rd ';
tmpstr:=tmpstr+'-pix_fmt yuv'+ComboBox3.Text[1]+ComboBox3.Text[3]+ComboBox3.Text[5]+'p ';
If SpinEdit14.Value>0 then tmpstr:=tmpstr+'-trellis '+IntToStr(SpinEdit14.Value)+' ';
If radioButton34.checked then tmpstr:=tmpstr+'-me_method epzs '
                         else tmpstr:=tmpstr+'-flags +mv4+aic ';
tmpstr:=tmpstr+'-g '+IntToStr(SpinEdit15.Value)+' ';
if SpinEdit16.Value>0 then tmpstr:=tmpstr+'-bf '+IntToStr(SpinEdit16.Value)+' ';
tmpstr:=tmpstr+'-cmp 2 -subcmp 2 -vcodec ';
If RadioButton34.Checked then tmpstr:=tmpstr+'mpeg2video ';
If RadioButton35.Checked then tmpstr:=tmpstr+'mpeg4 ';
If RadioButton36.Checked then tmpstr:=tmpstr+'libx264 ';
tmpstr:=tmpstr+'-an -y -t '+IntToStr(SpinEdit13.Value)+' -threads '+IntToStr(MySystem.dwNumberOfProcessors)+' ';
If RadioButton15.Checked then tmpstr:=tmpstr+'-vf mp=noise='+IntToStr(Round(1000/SpinEdit3.Value))+':'+IntToStr(Round(1000/SpinEdit3.Value))+'ut ';
If RadioButton16.Checked then tmpstr:=tmpstr+'-vf mp=noise='+IntToStr(Round(1000/SpinEdit3.Value))+':'+IntToStr(Round(1000/SpinEdit3.Value))+'t ';
tmpstr:=tmpstr+#34+ExtractFileDir(Application.ExeName)+'\ffmpeg\result.avi'+#34;
tmpstr:=GetDOSOutPut(tmpstr,ExtractFileDir(Application.ExeName));
//Memo1.Lines.Add(tmpstr);
tmpstr:=ExtractFileDir(Application.ExeName)+'\ffmpeg\ffprobe -loglevel verbose -pretty -i '+#34+ExtractFileDir(Application.ExeName)+'\ffmpeg\result.avi'+#34+' 1>'+#34+ExtractFileDir(Application.ExeName)+'\ffmpeg\tmp.txt'+#34+' 2>&1';
GetDOSOutPut(tmpstr,ExtractFileDir(Application.ExeName));
tmpstr:=ExtractFileDir(Application.ExeName)+'\ffmpeg\tmp.txt';
memo2.lines.add(tmpstr);
Memo2.Lines.LoadFromFile(tmpstr);
framerate:=30;
bitrate:=300;
For i:=1 to Memo2.Lines.Count do begin
                                   j:=pos('bitrate',Memo2.Lines[i]);
                                   If j>0 then begin
                                               tmpstr:=Copy(Memo2.Lines[i],j+8,pos('kb/s',Memo2.Lines[i])-j-8);
                                               Val(tmpstr,bitrate,err1);
                                               end;
                                   j:=pos('fps',Memo2.Lines[i]);
                                   If j>0 then begin
                                               k:=j-1;
                                               Repeat
                                               k:=k-1;
                                               Until (Memo2.Lines[i][k]=',') or (k=0);
                                               tmpstr:=Copy(Memo2.Lines[i],k+1,j-k-1);
                                               tmpstr2:= StringReplace(tmpstr,'.',',', [rfReplaceAll]);
                                               Val(tmpstr2,framerate,err1);
                                               if tmpstr2<>tmpstr then framerate:=framerate+1;
                                               end;
                                   end;

tmpstr:='Кодирование завершено.'+#10+#13+'Размер одного кадра: '+IntToStr(Round(bitrate/framerate))+' кбит.'+#10+#13+'Поток при 30 кадрах в секунду: '+IntToStr(Round(bitrate/framerate*30))+' кбит/сек.';
Application.MessageBox(PChar(tmpstr),'Сообщение',mb_ok);

Button8.Enabled:=True;
Button8Click(Self);
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
FilterGraph.ClearGraph;
end;

procedure TForm1.Button8Click(Sender: TObject);
var
tmpstr:String;
begin
ToolButton1Click(self);
tmpstr:=ExtractFileDir(Application.ExeName)+'\ffmpeg\ffplay';
ShellExecute(handle,'open',PChar(tmpstr), PChar('-an '+#34+Edit2.Text+#34),'',SW_SHOWNORMAL);
tmpstr:=ExtractFileDir(Application.ExeName)+'\ffmpeg\ffplay';
ShellExecute(handle,'open',PChar(tmpstr), PChar('-an '+#34+ExtractFileDir(Application.ExeName)+'\ffmpeg\result.avi'+#34),'',SW_SHOWNORMAL);

end;

procedure TForm1.VideoWindow1Click(Sender: TObject);
begin
If FilterGraph.State=gsPlaying then FilterGraph.Pause else FilterGraph.Play;
end;

end.
