RLE解壓縮圖像
發表於 : 2020-09-28, 12:17
代碼: 選擇全部
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.