unit Unit1; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls, Menus, ExtDlgs, StdCtrls,Math; type TForm1 = class(TForm) MainMenu1: TMainMenu; N1: TMenuItem; Open: TMenuItem; OpenPictureDialog1: TOpenPictureDialog; ScrollBox1: TScrollBox; Image1: TImage; ScrollBox2: TScrollBox; Image2: TImage; N3: TMenuItem; ConvertYdCrCb: TMenuItem; Save: TMenuItem; N2: TMenuItem; SavePictureDialog1: TSavePictureDialog; YdCrCb1: TMenuItem; N444: TMenuItem; N422: TMenuItem; Label1: TLabel; N411: TMenuItem; N420: TMenuItem; SECAM1: TMenuItem; Yd1: TMenuItem; N4: TMenuItem; N5: TMenuItem; Label2: TLabel; Yd2: TMenuItem; N4101: TMenuItem; PAL1: TMenuItem; NTSC1: TMenuItem; N6: TMenuItem; Mono1: TMenuItem; N7: TMenuItem; N8: TMenuItem; N9: TMenuItem; N10: TMenuItem; N11: TMenuItem; N12: TMenuItem; N13: TMenuItem; procedure N2Click(Sender: TObject); procedure OpenClick(Sender: TObject); procedure ConvertYdCrCbClick(Sender: TObject); procedure SaveClick(Sender: TObject); procedure GetYdCrCb(x,y:smallint; var Yd,Cr,Cb:byte); procedure SetYdCrCb(x,y:smallint;Yd,Cr,Cb:byte); procedure DrawYdCrCb(xm,ym:smallint); procedure N444Click(Sender: TObject); procedure N422Click(Sender: TObject); procedure N411Click(Sender: TObject); procedure N420Click(Sender: TObject); procedure SECAM1Click(Sender: TObject); procedure N4Click(Sender: TObject); procedure N5Click(Sender: TObject); procedure Yd2Click(Sender: TObject); procedure N4101Click(Sender: TObject); procedure PAL1Click(Sender: TObject); procedure NTSC1Click(Sender: TObject); procedure N6Click(Sender: TObject); procedure Mono1Click(Sender: TObject); procedure SetYd(x,y:smallint;Yd:byte); procedure N7Click(Sender: TObject); procedure DataManchester(T:smallint;ToSize:boolean); procedure N8Click(Sender: TObject); procedure N10Click(Sender: TObject); procedure N11Click(Sender: TObject); procedure N12Click(Sender: TObject); private { Private declarations } public { Public declarations } end; const Rep=19;{(Число расчетных точек в течение периода передачи одного бита)-1.} Amp=5;{Амплитуда дополнительных данных} var Form1: TForm1; Yd,Cr,Cb:array[0..832,0..624] of byte; ADt:array[0..832,0..624] of shortint; Etalon:array[1..520625] of byte; Counter:LongInt; implementation uses Unit2, Unit3; {$R *.DFM} procedure TForm1.N2Click(Sender: TObject); begin close; end; procedure TForm1.OpenClick(Sender: TObject); var CurrentFile:string; begin if OpenPictureDialog1.Execute then begin CurrentFile:=OpenPictureDialog1.FileName; Image1.Picture.LoadFromFile(CurrentFile); Image2.Picture.LoadFromFile(CurrentFile); end; end; procedure TForm1.GetYdCrCb(x,y:smallint; var Yd,Cr,Cb:byte); var Ey,Er,Eg,Eb,Eby,Ery:double; R,G,B:byte; begin R:=GetRValue(image1.canvas.pixels[x,y]); G:=GetGValue(image1.canvas.pixels[x,y]); B:=GetBValue(image1.canvas.pixels[x,y]); Er:=R/255; Eg:=G/255; Eb:=B/255; Ey:=0.3*Er+0.59*Eg+0.11*Eb; Eby:=Eb-Ey; Ery:=Er-Ey; if Eby>0.886 then Eby:=0.886; if Eby<-0.886 then Eby:=-0.886; {Yd:=round(217*Ey+17);} Yd:=round(219*Ey+16); Cr:=round(112*Ery/0.701+128); Cb:=round(112*Eby/0.886+128); end; procedure TForm1.SetYdCrCb(x,y:smallint;Yd,Cr,Cb:byte); var Ey,Er,Eg,Eb,Eby,Ery:double; begin Ey:=(Yd-16)/219; Ery:=(Cr-128)/112*0.701; Eby:=(Cb-128)/112*0.886; Er:=abs(Ery+Ey); Eb:=abs(Eby+Ey); Eg:=abs((Ey-0.3*(Ery+Ey)-0.11*(Eby+Ey))/0.59); if Er>1 then Er:=1; if Eg>1 then Eg:=1; if Eb>1 then Eb:=1; Image2.Canvas.Pixels[x,y]:=colorref(rgb(round(Er*255),round(Eg*255),round(Eb*255))); end; procedure TForm1.ConvertYdCrCbClick(Sender: TObject); var w,h,x,y:smallint; begin form2.show; form2.refresh; w:=Image1.Width-1; h:=Image1.Height-1; for y:=0 to h do for x:=0 to w do GetYdCrCb(x,y,Yd[x,y],Cr[x,y],Cb[x,y]); form2.hide; end; procedure TForm1.SaveClick(Sender: TObject); var CurrentFile:string; begin if SavePictureDialog1.Execute then begin CurrentFile:=SavePictureDialog1.FileName; Image2.Picture.SaveToFile(CurrentFile); end; end; procedure TForm1.DrawYdCrCb(xm,ym:smallint); var w,h,x,y,i,j,x2,y2,Cr3,Cb3:smallint; Cr2,Cb2:byte; begin form2.show; form2.refresh; w:=Image1.Width-1; h:=Image1.Height-1; for y:=0 to h do for x:=0 to w do begin Cr3:=0; Cb3:=0; x2:=(x div (xm+1))*(xm+1); y2:=(y div (ym+1))*(ym+1); for i:=0 to xm do for j:=0 to ym do begin Cr3:=Cr3+Cr[x2+i,y2+j]; Cb3:=Cb3+Cb[x2+i,y2+j]; end; Cr2:=Cr3 div ((xm+1)*(ym+1)); Cb2:=Cb3 div ((xm+1)*(ym+1)); SetYdCrCb(x,y,Yd[x,y],Cr2,Cb2); end; form2.hide; end; procedure TForm1.N444Click(Sender: TObject); begin DrawYdCrCb(0,0); end; procedure TForm1.N422Click(Sender: TObject); begin DrawYdCrCb(1,0); end; procedure TForm1.N411Click(Sender: TObject); begin DrawYdCrCb(3,0); end; procedure TForm1.N420Click(Sender: TObject); begin DrawYdCrCb(1,1); end; procedure TForm1.SECAM1Click(Sender: TObject); var w,h,x,y,x3,i,Cr2,Cb2:smallint; ry,by:byte; begin form2.show; form2.refresh; w:=Image1.Width-1; h:=Image1.Height-1; for y:=0 to h do for x:=0 to w do begin x3:=x and (not 3); case (y and 2) of 0:begin Cb2:=0;Cr2:=0; for i:=0 to 3 do begin Cb2:=Cb2+Cb[x3+i,y]; {if y<2 then ry:=Cr[x3,h-1+(y and 1)] else} Cr2:=Cr2+Cr[x3+i,y-2]; end; end; 2:begin Cb2:=0;Cr2:=0; for i:=0 to 3 do begin Cb2:=Cb2+Cb[x3+i,y-2]; {if y<2 then ry:=Cr[x3,h-1+(y and 1)] else} Cr2:=Cr2+Cr[x3+i,y]; end; end; end; ry:=Cr2 div 4; by:=Cb2 div 4; SetYdCrCb(x,y,Yd[x,y],ry,by); end; form2.hide; end; procedure Data2Yd(bgX,bgY,w:smallint; LocalCounter:LongInt; Base:byte); var x,y:smallint; i:LongInt; DataBit{,Temp}:byte; begin x:=bgX;y:=bgY; Yd[x,y]:=Base; inc(x); Randomize; if x>w then begin x:=0;inc(y); end; for i:=1 to LocalCounter do begin DataBit:=Round(Random(2)); Yd[x,y]:=Base+DataBit; {Temp:=Cr[x,y];Cr[x,y]:=Cb[x,y];Cb[x,y]:=Temp;} {Cr[x,y]:=Cr[x,y] Xor 128; Cb[x,y]:=Cb[x,y] Xor 128;} inc(x); if x>w then begin x:=0;inc(y); end; end; end; procedure Data2YdInv(bgX,bgY,w:smallint; LocalCounter:LongInt; Base:byte); var x,y:smallint; i:LongInt; DataBit{,Temp}:byte; begin x:=bgX;y:=bgY; Yd[x,y]:=Base; inc(x); Randomize; if x>w then begin x:=0;inc(y); end; for i:=1 to LocalCounter do begin DataBit:=Round(Random(2)); Yd[x,y]:=Base+DataBit; {Temp:=Cr[x,y];Cr[x,y]:=Cb[x,y];Cb[x,y]:=Temp;} Cr[x,y]:=Cr[x,y] Xor 128; Cb[x,y]:=Cb[x,y] Xor 128; inc(x); if x>w then begin x:=0;inc(y); end; end; end; procedure TForm1.N4Click(Sender: TObject); var w,h,x,y,bgX,bgY:smallint; GroupHeader,NowYd:byte; LocalCounter:LongInt; LegalGroup:Boolean; begin form2.show; form2.refresh; w:=Image1.Width-1; h:=Image1.Height-1; GroupHeader:=0; Counter:=0; LocalCounter:=0; LegalGroup:=False; for y:=0 to h do for x:=0 to w do begin NowYd:=Yd[x,y]; {Cr[x,y]:=128;Cb[x,y]:=128;} if (NowYd<(16+220)) and (NowYd>16) and (abs(NowYd-GroupHeader)<2) and (LegalGroup) then begin inc(LocalCounter); end else begin if LocalCounter>0 then begin Data2Yd(bgX,bgY,w,LocalCounter,GroupHeader); Counter:=Counter+LocalCounter; LocalCounter:=0; end; if (NowYd>16) and (NowYd<(219+16)) then begin GroupHeader:=NowYd; LegalGroup:=True; bgX:=x;bgY:=y; end else LegalGroup:=False; end; end; if LocalCounter>0 then begin Data2Yd(bgX,bgY,w,LocalCounter,GroupHeader); Counter:=Counter+LocalCounter; end; form2.hide; Label1.Caption:=IntToStr(Counter); end; procedure TForm1.N5Click(Sender: TObject); var w,h,x,y,bgX,bgY:smallint; GroupHeader,NowYd:byte; LocalCounter:LongInt; LegalGroup:Boolean; begin form2.show; form2.refresh; w:=Image1.Width-1; h:=Image1.Height-1; GroupHeader:=0; Counter:=0; LocalCounter:=0; LegalGroup:=False; for y:=0 to h do for x:=0 to w do begin NowYd:=Yd[x,y]; {Cr[x,y]:=128;Cb[x,y]:=128;} if (NowYd<(16+220)) and (NowYd>16) and (abs(NowYd-GroupHeader)<2) and (LegalGroup) then begin inc(LocalCounter); end else begin if LocalCounter>0 then begin Data2YdInv(bgX,bgY,w,LocalCounter,GroupHeader); Counter:=Counter+LocalCounter; LocalCounter:=0; end; if (NowYd>16) and (NowYd<(219+16)) then begin GroupHeader:=NowYd; LegalGroup:=True; bgX:=x;bgY:=y; end else LegalGroup:=False; end; end; if LocalCounter>0 then begin Data2YdInv(bgX,bgY,w,LocalCounter,GroupHeader); Counter:=Counter+LocalCounter; end; form2.hide; Label1.Caption:=IntToStr(Counter); end; procedure TForm1.Yd2Click(Sender: TObject); var w,h,x,y,bgX,bgY:smallint; Base,NowYd:byte; LocalCounter,Counter2:LongInt; LegalGroup:Boolean; begin form2.show; form2.refresh; w:=Image1.Width-1; h:=Image1.Height-1; Base:=0; Counter2:=0; LocalCounter:=0; LegalGroup:=False; for y:=0 to h do for x:=0 to w do begin NowYd:=Yd[x,y]; if (NowYd<(16+220)) and (NowYd>16) and (((NowYd-Base)=0) or ((NowYd-Base)=1)) and (LegalGroup) then begin inc(LocalCounter); end else begin if LocalCounter>0 then begin Counter2:=Counter2+LocalCounter; LocalCounter:=0; end; if (NowYd>16) and (NowYd<(219+16)) then begin Base:=NowYd; bgX:=x;bgY:=y; LegalGroup:=True; end else LegalGroup:=False; end; end; if LocalCounter>0 then begin Counter2:=Counter2+LocalCounter; end; form2.hide; Label2.Caption:=IntToStr(Counter2); end; procedure TForm1.N4101Click(Sender: TObject); begin DrawYdCrCb(3,3); end; procedure TForm1.PAL1Click(Sender: TObject); begin DrawYdCrCb(2,0); end; procedure TForm1.NTSC1Click(Sender: TObject); var w,h,x,y,j,x2,y2:smallint; Cr2,Cb2:byte; I,Q:double; begin form2.show; form2.refresh; w:=Image1.Width-1; h:=Image1.Height-1; for y:=0 to h do for x:=0 to w do begin I:=0; Q:=0; x2:=(x div 3)*3; for j:=0 to 2 do I:=I-0.27*Cb[x2+j,y]+0.74*Cr[x2+j,y]; I:=I/3; x2:=(x div 7)*7; for j:=0 to 6 do Q:=Q+0.41*Cb[x2+j,y]+0.48*Cr[x2+j,y]; Q:=Q/7; Cb2:=round(1.72*Q-1.117*I); Cr2:=round(2.08*Q-0.854*Cb2); SetYdCrCb(x,y,Yd[x,y],Cr2,Cb2); end; form2.hide; end; procedure TForm1.N6Click(Sender: TObject); begin form3.show; end; procedure TForm1.DataManchester(T:smallint;ToSize:boolean); var w,h,x,y,a:smallint; i,j,countd,countz:longint; DataBit:byte; busy:boolean; begin Randomize; form2.show; form2.refresh; if ToSize then begin w:=Image1.Width-1; h:=Image1.Height-1; end else begin w:=832;h:=624; end; countd:=((w+1)*(h+1)) div (T*2); countz:=((w+1)*(h+1)) mod (T*2); busy:=false; x:=0;y:=0; a:=1; for i:=1 to countd do begin DataBit:=Round(Random(2)); case DataBit of 0:begin for j:=1 to T do begin ADt[x,y]:=a; inc(x); if x>w then begin x:=0;inc(y); end; end; for j:=1 to T do begin ADt[x,y]:=-a; inc(x); if x>w then begin x:=0;inc(y); end; end; end; 1:begin for j:=1 to T do begin ADt[x,y]:=-a; inc(x); if x>w then begin x:=0;inc(y); end; end; for j:=1 to T do begin ADt[x,y]:=a; inc(x); if x>w then begin x:=0;inc(y); end; end; end; end; end; for i:=1 to countz do begin ADt[x,y]:=0; inc(x); if x>w then begin x:=0;inc(y); end; end; form2.hide; end; procedure TForm1.SetYd(x,y:smallint;Yd:byte); var Ey:byte; begin Ey:=round((Yd-16)/219*255); {if Ey>255 then Ey:=255; if Ey<0 then Ey:=0;} Image2.Canvas.Pixels[x,y]:=colorref(rgb(Ey,Ey,Ey)); end; procedure TForm1.Mono1Click(Sender: TObject); var w,h,x,y,i,j:smallint; begin form2.show; form2.refresh; w:=Image1.Width-1; h:=Image1.Height-1; for y:=0 to h do for x:=0 to w do begin SetYd(x,y,Yd[x,y]); end; form2.hide; end; procedure TForm1.N7Click(Sender: TObject); var w,h,x,y,i,j:smallint; sum:int64; tmp:byte; x1,x2,y1,y2,k1,k2,f1,f2,f1f,f2f,ie2f,ie2,deltat:double; begin form2.show; form2.refresh; { w:=Image1.Width-1; h:=Image1.Height-1;} w:=832;h:=624; sum:=0; { for y:=0 to h do for x:=0 to w do begin sum:=sum+ADt[x,y]; end;} y2:=sum / ((w+1)*(h+1)); x2:=0; k1:=0.1121; k2:=0.7758; { k1:=0.61; k2:=-0.22;} ie2f:=0; ie2:=0; deltat:=1/12e6; for y:=0 to h do for x:=0 to w do begin x1:=ADt[x,y]; y1:=k1*x1+k1*x2+k2*y2; { tmp:=round(y1); if tmp>(219+16) then tmp:=(219+16); if tmp<16 then tmp:=16; Yd[x,y]:=tmp;} if (x=0) and (y=0) then begin f1f:=sqr(y1); f1:=sqr(x1); end else begin f2:=sqr(x1); ie2:=ie2+(f1+f2)/2*deltat; f1:=f2; f2f:=sqr(y1); ie2f:=ie2f+(f1f+f2f)/2*deltat; f1f:=f2f; end; x2:=x1; y2:=y1; end; form2.hide; Label1.Caption:=FloatToStr(ie2); Label2.Caption:=FloatToStr(ie2f); end; procedure TForm1.N8Click(Sender: TObject); var w,h,x,y,i,j,tmp:smallint; sum:int64; {tmp:byte;} x1,x2,y1,y2,k1,k2,f1,f2,f1f,f2f,ie2f,ie2,deltat,ww:double; begin form2.show; form2.refresh; w:=Image1.Width-1; h:=Image1.Height-1; {w:=832;h:=624;} for y:=0 to h do for x:=0 to w do begin Yd[x,y]:=(Yd[x,y]-16)*217 div 219 +17 end; sum:=0; for y:=0 to h do for x:=0 to w do begin sum:=sum+Yd[x,y]+ADt[x,y]; end; y2:=sum / ((w+1)*(h+1)); x2:=y2; {0.5 MHz, Fs=12 MHz} {k1:=0.1121;} {6 MHz, Fs=12 MHz} {k1:=0.6;} {5 MHz, Fs=12 MHz} { k1:=0.5556;} {1.5 MHz, Fs=12 MHz} {k1:=0.27;} {3 MHz, Fs=12 MHz} {k1:=0.4286;} {6 MHz, Fs=13.5 MHz} {k1:=0.57;} {6 MHz, Fs=30 MHz} {k1:=0.375;} {3 MHz, Fs=30 MHz} {k1:=0.231;} {1.5 Mhz, Fs=30 MHz} {k1:=0.13;} {0.5 MHz, Fs=30 MHz} {k1:=0.05;} ww:=0.45; k1:=1/(1+1/(tan(pi*ww))); k2:=1-k1*2; ie2f:=0; ie2:=0; deltat:=1;{1/12e6;} for y:=0 to h do for x:=0 to w do begin x1:=Yd[x,y]+ADt[x,y]; y1:=k1*x1+k1*x2+k2*y2; tmp:=round(y1); if tmp>(219+16) then tmp:=(219+16); if tmp<16 then tmp:=16; if (x=0) and (y=0) then begin f1f:=sqr(tmp-Yd[x,y]); {f1:=sqr(x1);} end else begin {f2:=sqr(x1); ie2:=ie2+(f1+f2)/2*deltat; f1:=f2;} f2f:=sqr(tmp-Yd[x,y]); ie2f:=ie2f+(f1f+f2f)/2*deltat; f1f:=f2f; end; x2:=x1; y2:=y1; Yd[x,y]:=tmp; end; form2.hide; Label2.Caption:=FloatToStr(k1);{'---';}{FloatToStr(ie2);} Label1.Caption:=FloatToStr(ie2f); end; procedure TForm1.N10Click(Sender: TObject); var w,h,x,y:smallint; i,j,countd:longint; DataBit:byte; begin Randomize; form2.show; form2.refresh; w:=Image1.Width; h:=Image1.Height; countd:=w*h div (Rep+1); dec(w); x:=0;y:=0; for i:=1 to countd do begin DataBit:=Round(Random(2)); Etalon[i]:=DataBit; case DataBit of 0:begin for j:=0 to rep do begin ADt[x,y]:=round(Amp*cos(j*pi)); inc(x); if x>w then begin x:=0;inc(y); end; end; end; 1:begin for j:=0 to rep do begin ADt[x,y]:=round(-Amp*cos(j*pi)); inc(x); if x>w then begin x:=0;inc(y); end; end; end; end; end; form2.hide; end; procedure TForm1.N11Click(Sender: TObject); var w,h,x,y,u0:smallint; i,j,countd,er:longint; DataBit:byte; z,f1,f2,integr:double; begin form2.show; form2.refresh; w:=Image1.Width; h:=Image1.Height; countd:=w*h div (Rep+1); dec(w); x:=0;y:=0;er:=0; for i:=1 to countd do begin integr:=0; for j:=0 to rep do begin u0:=round(Amp*cos(j*pi)); z:=Yd[x,y]+ADt[x,y]; if z<16 then z:=16; if z>(219+16) then z:=(219+16); z:=z*u0; if j<>0 then begin f2:=z; integr:=integr+(f1+f2)/2; f1:=f2; end else begin f1:=z; end; inc(x); if x>w then begin x:=0;inc(y); end; end; if integr<0 then DataBit:=1; if integr>=0 then DataBit:=0; if DataBit<>Etalon[i] then inc(er); end; form2.hide; Label1.caption:=inttostr(countd); label2.caption:=inttostr(er); end; procedure TForm1.N12Click(Sender: TObject); var w,h,x,y:smallint; i,j,countd:longint; z:double; begin form2.show; form2.refresh; w:=Image1.Width; h:=Image1.Height; countd:=w*h div (Rep+1); dec(w); x:=0;y:=0; for i:=1 to countd do begin for j:=0 to rep do begin z:=round(Yd[x,y]+ADt[x,y]); if z<16 then z:=16; if z>(219+16) then z:=(219+16); Yd[x,y]:=round(z); inc(x); if x>w then begin x:=0;inc(y); end; end; end; form2.hide; end; end.