RLE解壓縮圖像

୧༼✿ ͡◕ д ◕͡ ༽୨ 法蘭城的約定
回覆文章
fantastic
技術組
文章: 33
註冊時間: 2020-08-25, 14:03

RLE解壓縮圖像

文章 fantastic »

代碼: 選擇全部

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ExtCtrls;

type
  TForm1 = class(TForm)
    Image1: TImage;
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

type GraphicInfo = record
  GraphicID: Dword;
  StartAddress: Dword;
  DataLength: Dword;
  Xpos: Dword;
  YPos: Dword;
  Width: Dword;
  High: Dword;
  East: Dword;
  South: Dword;
  Walk: Byte;
  Unk: Dword;
  IamgeID: Dword;
end;

type RDHead = record
  RDMagic: Word;
  Compress: Byte;
  Unk: Byte;
  Width: Dword;
  High: Dword;
  Length: Dword;
  V3PalLength: Dword; // ?????????
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  GInfo, Graphic, Palbin: TFileStream;
  ImageStream: TMemoryStream;
  i, LCount, Cycle: Integer;
  BTemp, Xix: Byte;
  WTemp: Word;
  DTemp: Dword;
  Information: GraphicInfo; // ????
  RD: RDHead;               // RD?
begin
  if not Fileexists('bin\GraphicInfo_66.bin') then
  begin
    ShowMessage(' ?????????!');
    Exit;
  end;
  if not Fileexists('bin\Graphic_66.bin') then
  begin
    ShowMessage(' ?????????!');
    Exit;
  end;
  if not Fileexists('Pal.bin') then
  begin
    ShowMessage(' Pal.bin?????!');
    Exit;
  end;

  GInfo:= TFileStream.Create('bin\GraphicInfo_66.bin', fmOpenRead);
  Graphic:= TFileStream.Create('bin\Graphic_66.bin', fmOpenRead);
  GInfo.Seek(0, 0);
  with GInfo do
  begin
    Read(Information.GraphicID, sizeof(Dword));
    Read(Information.StartAddress, sizeof(Dword));
    Read(Information.DataLength, sizeof(Dword));
    Read(Information.Xpos, sizeof(Dword));
    Read(Information.YPos, sizeof(Dword));
    Read(Information.Width, sizeof(Dword));
    Read(Information.High, sizeof(Dword));
    Read(Information.East, sizeof(Dword));
    Read(Information.South, sizeof(Dword));
    Read(Information.Walk, sizeof(Dword));
    Read(Information.Unk, sizeof(Dword));
    Read(Information.IamgeID, sizeof(Dword));
  end;
  GInfo.Free;

  ImageStream:= TMemoryStream.Create;
  BTemp:= $42; ImageStream.Write(BTemp, sizeof(BTemp));
  BTemp:= $4D; ImageStream.Write(BTemp, sizeof(BTemp));
  BTemp:= $F6; ImageStream.Write(BTemp, sizeof(BTemp));
  BTemp:= $0F; ImageStream.Write(BTemp, sizeof(BTemp));
  WTemp:= $0000;
  for i := 1 to 3 do
  begin
    ImageStream.Write(WTemp, sizeof(Word));
  end;

  Graphic.Seek(Information.StartAddress, 0);
  with Graphic do
  begin
    Read(RD.RDMagic, sizeof(Word));
    Read(RD.Compress, sizeof(Byte));
    Read(RD.Unk, sizeof(Byte));
    Read(RD.Width, sizeof(Dword));
    Read(RD.High, sizeof(Dword));
    Read(RD.Length, sizeof(Dword));
  end;
  if RD.Compress = $01 then
  begin
    BTemp:= $36; ImageStream.Write(BTemp, sizeof(Byte)); // 256?
    BTemp:= $04; ImageStream.Write(BTemp, sizeof(Byte));
    BTemp:= $00; ImageStream.Write(BTemp, sizeof(Byte));
    BTemp:= $00; ImageStream.Write(BTemp, sizeof(Byte));
    DTemp:= $28; ImageStream.Write(DTemp, sizeof(Dword));
    ImageStream.Write(RD.Width, sizeof(Dword));
    ImageStream.Write(RD.High, sizeof(Dword));
    WTemp:= $01; ImageStream.Write(WTemp, sizeof(Word));
    WTemp:= $08; ImageStream.Write(WTemp, sizeof(Word));
    DTemp:= $00; ImageStream.Write(DTemp, sizeof(Dword));
    for i := 1 to 5 do
      ImageStream.Write(DTemp, sizeof(Dword));           // ???????

    Palbin:= TFileStream.Create('Pal.bin', fmOpenRead);
    Palbin.Seek(0, 0);
    for i := 1 to 256 do
      begin
        Palbin.Read(DTemp, sizeof(Dword));
        ImageStream.Write(DTemp, sizeof(Dword));
      end;
    Palbin.Free;
  end;
  LCount:= RD.Length - 16;
  while LCount > 0 do
  begin
    Graphic.Read(BTemp, sizeof(Byte));
    if BTemp in [$00..$0F] then
    begin
      Cycle:= (BTemp and $0F);
      for i := 1 to Cycle do
        begin
          Graphic.Read(BTemp, sizeof(Byte));
          ImageStream.Write(BTemp, sizeof(Byte));
        end;
      LCount:= LCount - (Cycle + 1);
    end;

    if BTemp in [$10..$1F] then
    begin
      Cycle:= (BTemp and $0F) * 100;     // 1a
      Graphic.Read(BTemp, sizeof(Byte)); // bb
      Cycle:= Cycle + BTemp;
      for i := 1 to Cycle do
        begin
          Graphic.Read(BTemp, sizeof(Byte)); // xx
          ImageStream.Write(BTemp, sizeof(Byte));
        end;
      LCount:= LCount - (Cycle + 2);
    end;

    if BTemp in [$20..$2F] then
    begin
      Cycle:= (BTemp and $0F) * 10000;   // 2a
      Graphic.Read(BTemp, sizeof(Byte)); // bb
      Cycle:= Cycle + (BTemp * 100);     // cc
      for i := 1 to Cycle do
        begin
          Graphic.Read(BTemp, sizeof(Byte)); // xx
          ImageStream.Write(BTemp, sizeof(Byte));
        end;
      LCount:= LCount - (Cycle + 3);
    end;

    if BTemp in [$80..$8F] then
    begin
      Cycle:= (BTemp and $0F);           // 8a
      Graphic.Read(BTemp, sizeof(Byte)); // xx
      for i := 1 to Cycle do
        begin
          ImageStream.Write(BTemp, sizeof(Byte));
        end;
      LCount:= LCount - 2;
    end;

    if BTemp in [$90..$9F] then
    begin
      Cycle:= (BTemp and $0F) * 100;     // 9a
      Graphic.Read(Xix, sizeof(Byte));   // xx
      Graphic.Read(BTemp, sizeof(Byte)); // bb
      Cycle:= Cycle + BTemp;
      for i := 1 to Cycle do
        begin
          ImageStream.Write(Xix, sizeof(Byte));
        end;
      LCount:= LCount - 3;
    end;

    if BTemp in [$A0..$AF] then
    begin
      Cycle:= (BTemp and $0F) * 10000;   // Aa
      Graphic.Read(Xix, sizeof(Byte));   // xx
      Graphic.Read(BTemp, sizeof(Byte)); // bb
      Cycle:= Cycle + (BTemp * 100);
      Graphic.Read(BTemp, sizeof(Byte)); // cc
      Cycle:= Cycle + BTemp;
      for i := 1 to Cycle do
        begin
          ImageStream.Write(Xix, sizeof(Byte));
        end;
      LCount:= LCount - 4;
    end;

    if BTemp in [$C0..$CF] then
    begin
      Cycle:= (BTemp and $0F);          // Ca
      BTemp:= $00;                      // ???
      for i := 1 to Cycle do
        begin
          ImageStream.Write(BTemp, sizeof(Byte));
        end;
      LCount:= LCount - 1;
    end;

    if BTemp in [$D0..$DF] then
    begin
      Cycle:= (BTemp and $0F) * 100;    // Da
      Graphic.Read(BTemp, sizeof(Byte));// bb
      Cycle:= Cycle + BTemp;
      BTemp:= $00;                      // ???
      for i := 1 to Cycle do
        begin
          ImageStream.Write(BTemp, sizeof(Byte));
        end;
      LCount:= LCount - 2;
    end;

    if BTemp in [$E0..$EF] then
    begin
      Cycle:= (BTemp and $0F) * 10000;  // Ea
      Graphic.Read(BTemp, sizeof(Byte));// bb
      Cycle:= Cycle + (BTemp * 100);
      Graphic.Read(BTemp, sizeof(Byte));// cc
      Cycle:= Cycle + BTemp;
      BTemp:= $00;                      // ???
      for i := 1 to Cycle do
        begin
          ImageStream.Write(BTemp, sizeof(Byte));
        end;
      LCount:= LCount - 3;
    end;
  end;
  ImageStream.Seek(0, 0);
  Image1.Picture.LoadFromStream(ImageStream);
  Graphic.Free;
//  ImageStream.SaveToFile('test.bmp');
  ImageStream.Free;
end;

end.
120262370_1730235930482870_9014569366971001526_o.jpg
120262370_1730235930482870_9014569366971001526_o.jpg (10.55 KiB) 已瀏覽 650 次
Jrnomdj.jpg
Jrnomdj.jpg (17.25 KiB) 已瀏覽 650 次
7EDcoJJ.jpg
7EDcoJJ.jpg (16.79 KiB) 已瀏覽 650 次
回覆文章