unit UJVuBasics;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, jpeg, Gauges, ExtCtrls;

const
  JpgDatei = 1;
  BmpDatei = 2;

type
  TFormJVuBasics = class(TForm)
    Memo1: TMemo;
    ImageHG: TImage;
    procedure FormCreate(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
    procedure SaveJniPas(MainWindowBounds:TRect);
  end;

var
  FormJVuBasics: TFormJVuBasics;
  GlobalJpg: TJPEGImage;
  GlobalBmp,BmpRueck: TBitmap;
  GlobalGauge: TGauge;
  GlobalSize:Integer;
  GlobalComment:String;

  ZoomInt: array[0..19] of integer = (10,20,30,40,50,60,66,75,80,90,100,150,200,250,300,400,500,600,800,1000);

  function DateiTyp(Dateiname:String):integer;
  procedure BildLaden(Dateiname:String);
  procedure BildSpeichern(Dateiname:String; Kompression:Integer);
  procedure JpgSpeichernMitKommentar(Dateiname:String);
  procedure BildDrehen(TheBmp:TBitmap; dreh:Integer; Adjust:boolean);

implementation

{$R *.DFM}

function DateiTyp(Dateiname:String):integer;
begin
  Result:=0;
  if pos('.JPG',ansiuppercase(Dateiname)) > 0 then Result:=JpgDatei;
  if pos('.BMP',ansiuppercase(Dateiname)) > 0 then Result:=BmpDatei;
end;

procedure BildLaden(Dateiname:String);
// Lädt eine bmp- oder jpg-Datei in GlobalBmp
// Benutzt GlobalJpg,GlobalSize,GlobalComment
var i,n:integer; c:PByteArray; MS:TMemoryStream;
begin
  GlobalComment:='';
  MS:=TMemoryStream.Create;
  MS.LoadFromFile(Dateiname);
  GlobalSize:=MS.Size;
  if DateiTyp(Dateiname) = JpgDatei then begin
    //GetJpgKommentar;
    c:=MS.Memory;
    if c[6] = ord('J') then if c[7] = ord('F') then begin
      if c[20] = 255 then if c[21] = 254 then begin
        n:=c[23];
        for i:=0 to n-3 do GlobalComment:=GlobalComment+chr(c[24+i]);
      end;
    end;
    GlobalJpg.LoadFromStream(MS);
    GlobalBmp.Assign(GlobalJpg);
  end;
  if DateiTyp(Dateiname) = BmpDatei then begin
    GlobalBmp.LoadFromStream(MS);
  end;
  MS.Free;
end;

procedure BildSpeichern(Dateiname:String; Kompression:Integer);
// Speichert GlobalBmp in eine bmp- oder jpg-Datei
// Bei jpg ggf. mit Kommentar und Datenkompression
// Benutzt GlobalJpg
begin
  if DateiTyp(Dateiname) = JpgDatei then begin
    GlobalJpg.Assign(GlobalBmp);
    GlobalJpg.CompressionQuality:=Kompression;
    GlobalJpg.Compress;
    GlobalJpg.Smoothing:=not GlobalJpg.Smoothing;
    GlobalBmp.Assign(GlobalJpg);
    JpgSpeichernMitKommentar(Dateiname);
  end;
  if DateiTyp(Dateiname) = BmpDatei then begin
    GlobalBmp.SaveToFile(Dateiname);
  end;
end;

procedure JpgSpeichernMitKommentar(Dateiname:String);
// Speichert GlobalJpg mit Kommentar über einen Memorystream in eine jpg-Datei
// Benutzt GlobalComment
var i,lg:Integer; c,c2:PByteArray; MS,MS2:TMemoryStream;
begin
  if GlobalComment = '' then begin
    GlobalJpg.SaveToFile(Dateiname);
    exit;
  end;
  MS:=TMemoryStream.Create;
  MS2:=TMemoryStream.Create;
  GlobalJpg.SaveToStream(MS);
  lg:=Length(GlobalComment);
  MS2.SetSize(MS.Size+4+lg);
  c:=MS.Memory;
  c2:=MS2.Memory;
  for i:=0 to 19 do c2[i]:=c[i];
  c2[20]:=255; c2[21]:=254; c2[22]:=0; c2[23]:=2+lg;
  for i:=0 to lg-1 do c2[24+i]:=ord(GlobalComment[i+1]);
  for i:=20 to MS.Size-1 do c2[i+4+lg]:=c[i];
  MS2.SaveToFile(Dateiname);
  MS2.Free;
  MS.Free;
end;

procedure BildDrehen(TheBmp:TBitmap; dreh:Integer; Adjust:boolean);
var i,j,k,m,n,n3,i3:Integer; cd,sd,dx,dy: double; p1,p2: PByteArray;
begin
  //vor Aufruf dieser Proc muss das Ursprungsbild in GlobalBmp kopiert werden
  if dreh = 0 then exit;
  cd:=cos(-dreh*pi/180.0); sd:=sin(-dreh*pi/180.0);
  if -dreh < 0 then dx:=GlobalBmp.Height*sd else dx:=0;
  if -dreh > 0 then dy:=GlobalBmp.Width*sd else dy:=0;
  TheBmp.Width:=trunc(abs(GlobalBmp.Width*cd)+abs(GlobalBmp.Height*sd));
  TheBmp.Height:=trunc(abs(GlobalBmp.Width*sd)+abs(GlobalBmp.Height*cd));
  TheBmp.Canvas.Brush.Color:=$02ffffff;
  TheBmp.Canvas.FillRect(Rect(0,0,TheBmp.Width,TheBmp.Height));
  GlobalGauge.MaxValue:=100;
  for j:=0 to TheBmp.Height-1 do begin
    p1:=TheBmp.ScanLine[j];
    for i:=0 to TheBmp.Width-1 do begin
      n:=trunc((i+dx+0.5)*cd-(j-dy-0.5)*sd);
      m:=trunc((j-dy-0.5)*cd+(i+dx+0.5)*sd);
      if n >= 0 then if n < GlobalBmp.Width then if m >=0 then if m < GlobalBmp.Height then begin
        p2:=GlobalBmp.ScanLine[m];
        for k:=0 to 2 do p1[i*3+k]:=p2[n*3+k];
      end;
    end;
    GlobalGauge.Progress:=Trunc(j/TheBmp.Height*100);
  end;
  if Adjust then begin
    TheBmp.Canvas.StretchDraw(Rect(0,0,GlobalBmp.Width,GlobalBmp.Height),TheBmp);
    TheBmp.Width:=GlobalBmp.Width;
    TheBmp.Height:=GlobalBmp.Height;
  end;
end;

//##### Formular #####

procedure TFormJVuBasics.FormCreate(Sender: TObject);
begin
  GlobalJpg:=TJPEGImage.Create;
  GlobalBmp:=TBitmap.Create;
  BmpRueck:=TBitmap.Create;
  GlobalComment:='';
  GlobalSize:=0;
  if FileExists(ExtractFilePath(ParamStr(0))+'jni.pas') then begin
    Memo1.Lines.LoadFromFile(ExtractFilePath(ParamStr(0))+'jni.pas');
  end;
end;

procedure TFormJVuBasics.SaveJniPas(MainWindowBounds:TRect);
begin
  Memo1.Clear;
  with MainWindowBounds do begin
    Memo1.Lines.Add(IntToStr(Left));
    Memo1.Lines.Add(IntToStr(Top));
    Memo1.Lines.Add(IntToStr(Right-Left));
    Memo1.Lines.Add(IntToStr(Bottom-Top));
  end;
  Memo1.Lines.SaveToFile(ExtractFilePath(ParamStr(0))+'jni.pas');
end;

end.

