{
   This program is free software; you can redistribute it and/or
  modify it under the terms of the GNU General Public License
  as published by the Free Software Foundation; either
  version 2 of the License, or (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
}
unit Ufrmextract;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ComCtrls, Buttons, gifimage, gr32,
  FreeBitmap, FreeImage, FreeUtils;

type
  Textracttype = (extgif, exttiff);

  Tfrmextract = class(TForm)
    Label2: TLabel;
    Label1: TLabel;
    ComboBox1: TComboBox;
    Edit1: TEdit;
    Button1: TButton;
    btnok: TBitBtn;
    btncancel: TBitBtn;
    ProgressBar1: TProgressBar;
    Label3: TLabel;
    Memo1: TMemo;
    procedure ComboBox1Change(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure btnokClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
    procedure btncancelClick(Sender: TObject);
  private
    { Private declarations }
    working,stopped:boolean;
    procedure proc_gif();
    procedure proc_tiff();
  public
    { Public declarations }
    extracttype:Textracttype;
    gif:tgifimage;
  end;

var
  frmextract: Tfrmextract;

implementation
uses Ufrmmain, Ufrmsaveopt, Ufunction, Uconfig, Ufrmworkbase, Uexistmsg;
{$R *.dfm}

procedure Tfrmextract.ComboBox1Change(Sender: TObject);
var
  f:FREE_IMAGE_FORMAT;
begin
  f:=FIU_GetFIFType2(FIU_GetSelectExt(ComboBox1.ItemIndex+1));
  case f of
    FIF_BMP,FIF_JPEG,FIF_PNG,FIF_TIFF:
      Button1.Enabled:=true;
    else
      Button1.Enabled:=false;
  end;
  Button1.Tag:=f;
end;

procedure Tfrmextract.Button1Click(Sender: TObject);
begin
  frmsaveopt:=Tfrmsaveopt.Create(self);
  try
    frmsaveopt.selectformat:=Button1.Tag;
    if frmsaveopt.ShowModal=mrok then ;
  finally
    frmsaveopt.Free;
  end;
end;

procedure Tfrmextract.btnokClick(Sender: TObject);
begin
  case self.extracttype of
    extgif: proc_gif();
    exttiff: proc_tiff();
  end;
end;

procedure Tfrmextract.FormCreate(Sender: TObject);
var
  strlist:tstringlist;
  i:integer;
begin
  strlist:=tstringlist.Create;
  try
    SplitString(FIU_GetAllFilters3,strlist,'^');
    for i:=0 to strlist.Count-1 do begin
      ComboBox1.Items.Add(strlist.Strings[i])
    end;
    if ComboBox1.Items.Count>config.c_lastselfiletype then
      ComboBox1.ItemIndex:=config.c_lastselfiletype;
    ComboBox1Change(nil);
  finally
    strlist.Free;
  end;
end;

procedure Tfrmextract.FormDestroy(Sender: TObject);
begin
  config.c_lastselfiletype:=ComboBox1.ItemIndex;
end;

procedure Tfrmextract.proc_gif();
var
  s,filename,path:string;
  i:integer;
  FBitmap:TFreeWinBitmap;
  stream:tmemorystream;
  FreeMemoryIO1:TFreeMemoryIO;
  selectsaveflag:integer;
begin
  existnoanswer:=false;
  path:=config.lastdir;
  if AdvSelectDirectory(handle,'저장할 폴더선택', '', Path, true, False, True)=false then
    exit;
  if path[length(path)]<>'\' then path:=path+'\';
  config.lastdir:=path;

  selectsaveflag:=get_reg_saveopt_flag(FIU_GetFIFType2(FIU_GetSelectExt(ComboBox1.ItemIndex+1)),false);

  memo1.Lines.Clear;
  ProgressBar1.Max:=gif.Images.Count;
  ProgressBar1.Position:=0;

  FBitmap:=TFreeWinBitmap.Create;
  stream:=tmemorystream.Create;
  stopped:=false;
  working:=true;
  btncancel.Caption:='취소';
  try
    edit1.Text:=deletebadfilenamechar(edit1.Text);

    for i:=0 to gif.Images.Count-1 do begin

      filename:=path+edit1.Text+format('%d',[i+1]);
      filename:=filename+FIU_GetSelectExt(ComboBox1.ItemIndex+1);

      ProgressBar1.Position:=i+1;
      Label3.Caption:=format('%d/%d (%s)',[i+1,gif.Images.Count,ExtractFileName(filename)]);

      if sysutils.FileExists(filename) then begin
        if existnoanswer=false then begin
          frmExistMsg:=TfrmExistMsg.Create(self);
          try
            frmExistMsg.Label1.Caption:=format('"%s" 파일이 존재합니다.',[ExtractFileName(filename)]);
            frmExistMsg.ShowModal;
          finally
            frmExistMsg.Free;
          end;
        end;
        case config.c_existmethod of
          0:filename:=makeuniqfilename(filename);
          1:continue;
        end;
        Label3.Caption:=format('%d/%d (%s)',[i+1,gif.Images.Count,ExtractFileName(filename)]);
      end;

      application.ProcessMessages;

      if gif.Images.SubImages[i].Bitmap=nil then
        continue;
      stream.Clear;
      gif.Images.SubImages[i].Bitmap.SaveToStream(stream);

      FreeMemoryIO1:=TFreeMemoryIO.Create(stream.Memory,stream.Size);
      try
        if FBitmap.LoadFromMemory(FreeMemoryIO1)=false then begin
          s:=format('%s 이미지를 읽을수 없습니다.',[ExtractFileName(filename)]);
          memo1.Lines.Add('>>'+s);
          SendMessage(memo1.Handle, WM_VSCROLL, SB_BOTTOM,0);
          continue;
        end;
      finally
        FreeMemoryIO1.Free;
      end;

      if FBitmap.Save(filename,selectsaveflag)=false then begin
        s:=format('%s 이미지를 저장할 수 없습니다.',[ExtractFileName(filename)]);
        memo1.Lines.Add('>>'+s);
        SendMessage(memo1.Handle, WM_VSCROLL, SB_BOTTOM,0);
      end;
    end;

    Label3.Caption:=Label3.Caption+' >> 완료되었습니다.';
  finally
    working:=false;
    btncancel.Caption:='닫기';
    stream.Free;
    FBitmap.Free;
  end;
end;

procedure Tfrmextract.proc_tiff();
var
  multipagebitmap:TFreeMultiBitmap;
  multipagebmp:TFreeWinBitmap;
  i,c:integer;
  s,path,filename:string;
begin
  existnoanswer:=false;
  path:=config.lastdir;
  if AdvSelectDirectory(handle,'저장할 폴더선택', '', Path, true, False, True)=false then
    exit;
  if path[length(path)]<>'\' then path:=path+'\';
  config.lastdir:=path;

  selectsaveflag:=get_reg_saveopt_flag(FIU_GetFIFType2(FIU_GetSelectExt(ComboBox1.ItemIndex+1)),false);

  memo1.Lines.Clear;

  multipagebitmap:=TFreeMultiBitmap.Create();
  multipagebmp:=TFreeWinBitmap.Create;
  stopped:=false;
  working:=true;
  btncancel.Caption:='취소';
  try
    if multipagebitmap.Open2(currentimage.name,FIF_TIFF,false,true)=false then begin
      s:=format('%s 이미지를 읽을수 없습니다.',[ExtractFileName(currentimage.name)]);
      memo1.Lines.Add('>>'+s);
      SendMessage(memo1.Handle, WM_VSCROLL, SB_BOTTOM,0);
      exit;
    end;

    c:=multipagebitmap.GetPageCount;
    if c=0 then begin
      s:=format('%s 페이지가 없습니다.',[ExtractFileName(currentimage.name)]);
      memo1.Lines.Add('>>'+s);
      SendMessage(memo1.Handle, WM_VSCROLL, SB_BOTTOM,0);
      exit;
    end;
    ProgressBar1.Max:=c;
    for i:=0 to c-1 do begin
      if stopped then break;
      filename:=path+edit1.Text+format('%d',[i+1]);
      filename:=filename+FIU_GetSelectExt(ComboBox1.ItemIndex+1);

      ProgressBar1.Position:=i+1;
      Label3.Caption:=format('%d/%d (%s)',[i+1,c,ExtractFileName(filename)]);

      if sysutils.FileExists(filename) then begin
        if existnoanswer=false then begin
          frmExistMsg:=TfrmExistMsg.Create(self);
          try
            frmExistMsg.Label1.Caption:=format('"%s" 파일이 존재합니다.',[ExtractFileName(filename)]);
            frmExistMsg.ShowModal;
          finally
            frmExistMsg.Free;
          end;
        end;
        case config.c_existmethod of
          0:filename:=makeuniqfilename(filename);
          1:continue;
        end;
        Label3.Caption:=format('%d/%d (%s)',[i+1,c,ExtractFileName(filename)]);
      end;

      application.ProcessMessages;

      if multipagebmp.IsValid then
        multipagebitmap.UnlockPage(multipagebmp, False);
      multipagebitmap.LockPage(i, multipagebmp);

      if multipagebmp.Save(filename,selectsaveflag)=false then begin
        s:=format('%s 이미지를 저장할 수 없습니다.',[ExtractFileName(filename)]);
        memo1.Lines.Add('>>'+s);
        SendMessage(memo1.Handle, WM_VSCROLL, SB_BOTTOM,0);
      end;

    end;

    if multipagebmp.IsValid then
      multipagebitmap.UnlockPage(multipagebmp, False);
    Label3.Caption:=Label3.Caption+' >> 완료되었습니다.';

  finally
    working:=false;
    btncancel.Caption:='닫기';
    multipagebmp.Free;
    multipagebitmap.Free;
  end;
end;

procedure Tfrmextract.FormCloseQuery(Sender: TObject;
  var CanClose: Boolean);
begin
  if working then
    canclose:=false;
end;

procedure Tfrmextract.btncancelClick(Sender: TObject);
begin
  if working then
    stopped:=true
  else
    self.ModalResult:=mrcancel;
end;

end.
