-
Notifications
You must be signed in to change notification settings - Fork 19
/
cGraphLoader.WB1.pas
163 lines (121 loc) · 4.56 KB
/
cGraphLoader.WB1.pas
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
UNIT cGraphLoader.WB1;
{=============================================================================================================
Gabriel Moraru
2023.08.05
See Copyright.txt
--------------------------------------------------------------------------------------------------------------
Decoder for WB1 file format
-------------------------------------------------------------------------------------------------------------}
INTERFACE
USES
System.SysUtils, System.Classes, ccStreamMem, Vcl.Imaging.jpeg,
System.AnsiStrings;
CONST
WB1 = '*.WB1';
WB1Ftl = 'WebShots|'+ WB1;
TYPE
TWb1Obj = class(TObject)
private
FFileName: string;
protected
procedure JpegNeeded;
public
JpgStream: TCubicMemStream;
InternalJPG: TJPEGImage;
constructor Create; { TObject is never directly instantiated. Although it does not use programming language features that prevent instantiation, TObject is an abstract class. }
destructor Destroy; override;
procedure Clear;
function LoadFromFile(CONST FullFileName: string): Boolean;
procedure SaveAsJpg(const FullFileName: string);
property FileName: string read FFileName;
end;
IMPLEMENTATION
{$WARN GARBAGE OFF} {Silence the: 'W1011 Text after final END' warning }
CONST
MAGIC_NUMBER0: AnsiString= 'WWBB0000';
MAGIC_NUMBER1: AnsiString= 'WWBB1111';
Key0 = $A4;
Key1 = $F2;
procedure TWb1Obj.Clear;
begin
{TODO: clear jpeg image here!!!!! }
{InternalJPG.DoClear }
JpgStream.Clear;
FFileName:= '';
end;
constructor TWb1Obj.Create;
begin
inherited Create;
InternalJPG:= TJPEGImage.Create;
JpgStream:= TCubicMemStream.Create;
end;
destructor TWb1Obj.Destroy;
begin
FreeAndNil(InternalJPG);
FreeAndNil(JpgStream);
inherited Destroy;
end;
function TWb1Obj.LoadFromFile(CONST FullFileName: string): Boolean;
VAR
WB1Stream: TCubicMemStream;
MagicHeader: array[1..8] of AnsiChar;
A100, B100, DecryptHeader: array[1..100] of Byte;
Count, Key, I: Integer;
begin
Clear;
FFileName:= FullFileName;
WB1Stream:= TCubicMemStream.Create;
TRY
{ Read magic number }
WB1Stream.LoadFromFile(FullFileName);
WB1Stream.Position := 0;
WB1Stream.ReadBuffer(MagicHeader, SizeOf(MagicHeader));
{ Magic number is ok? }
Result:= SameText(MagicHeader, MAGIC_NUMBER0) OR SameText(MagicHeader, MAGIC_NUMBER1);
if NOT Result then EXIT;
{ Find the right key }
if SameText(MagicHeader, MAGIC_NUMBER0)
then Key:= Key0
else Key:= Key1;
{ Read the encrypted bytes (200 or 100?!?) }
WB1Stream.ReadBuffer(A100, SizeOf(A100));
WB1Stream.ReadBuffer(B100, SizeOf(A100));
{ Decode 100 bytes }
for I:= 1 to Length(A100) DO { Formula: B(n) = (B(n) XOR (NOT A(n)) XOR key -> key = ‘F2’ (hex) }
DecryptHeader[I]:= (B100[I] XOR (NOT A100[I])) XOR Key;
{ Build the final JPEG image }
Count:= WB1Stream.Size- WB1Stream.Position;
JpgStream.WriteBuffer(DecryptHeader, SizeOf(DecryptHeader));
JpgStream.WriteBuffer(B100, SizeOf(B100));
JpgStream.CopyFrom(WB1Stream, Count); { Copy the rest of the image }
JpegNeeded;
FINALLY
FreeAndNil(WB1Stream);
end;
end;
procedure TWb1Obj.SaveAsJpg(CONST FullFileName: string);
begin
Assert(JpgStream<> NIL);
JpgStream.SaveToFile(FullFileName);
end;
procedure TWb1Obj.JpegNeeded; { Get a real JPEG from stream }
begin
Assert(JpgStream<> NIL);
JpgStream.Position:= 0;
InternalJPG.LoadFromStream(JpgStream);
end;
end.
(*
var sTemp, Data: AnsiString;
for I:= 1 to Length(DecryptHeader) DO
Data:= Data+ AnsiChar(DecryptHeader[i]);
for I:= 1 to Length(B100) DO
Data:= Data+ AnsiChar(B100[i]);
Count:= 20* MB; { I don't know how much I have to read so I TRY to read lots }
SetLength(sTemp, Count); { Make buffer large enough }
Count:= WB1Stream.Read(sTemp[1], Count); { Try to read LOTS. The function will return the actual number of read bytes }
SetLength(sTemp, Count); { Now I know how much I read }
Data:= Data+ sTemp;
WriteToFileA(AppData.CurFolder+ 'tst.jpg', Data, TRUE, TRUE);
IT WORKS!
*)