@jaenicke … das mit MMF ist mir noch ganz unbekannt. Las eben nur, dass es hier Sinn macht, wenn man große Daten liest.
Ich vergas noch die ReadMWord Funktion, die dabei war.
Delphi-Quellcode:
function ReadMWord(f: TFileStream): Word;
type
TMotorolaWord =
record
case Byte
of
0: (Value: Word);
1: (Byte1, Byte2: Byte);
end;
var
MW: TMotorolaWord;
begin
{ It would probably be better to just read these two bytes in normally }
{ and then do a small ASM routine to swap them. But we aren't talking }
{ about reading entire files, so I doubt the performance gain would be }
{ worth the trouble. }
f.
read(MW.Byte2, SizeOf(Byte));
f.
read(MW.Byte1, SizeOf(Byte));
Result := MW.Value;
end;
Eine extra Funktion wollte ich nicht und habe mir was zusammengebastelt. Was nun schneller oder langsamer ist, weiß ich jetzt nicht.
Mir ist die JPG Header Struktur sowieso noch nicht ganz klar. Es gibt da einige unterschiede.
Meine derzeitige Prozedur (siehe unten) scheint gut zu funktionieren. Mache mir nur noch Gedanken um den "While" Block. Nicht das hier (z.B. bei defekten JPG Dateien) einfach zu viel (wäre langsam) in der Datei gesucht wird und die Bildgröße gar nicht ermittelt (wäre dann nicht so schlimm) werden kann.
Delphi-Quellcode:
Procedure GetJPGSize(sFile: String; Out wWidth, wHeight: Word);
Var
FS: TFileStream;
BD: Byte;
WD : Word;
RL: LongInt;
HW : Array[0..3] Of Byte;
LE : Array[0..1] Of Byte;
Begin
sFile := '\\?\'+SFile;
wWidth := 0;
wHeight := 0;
FS := TFileStream.Create(sFile, fmShareDenyNone);
try
RL := FS.Read(WD, 2);
If (Lo(WD) <> $FF) And (Hi(WD) <> $D8) Then RL := 0;
If RL > 0 Then
Begin
RL := FS.Read(BD, 1);
While (BD = $FF) and (RL > 0) Do
Begin
RL := FS.Read(BD, 1);
If BD <> $FF Then
Begin
If BD In [$C0,$C1,$C2] Then
Begin
FS.Seek(3,1);
FS.Read(HW,4);
wHeight := HW[0] Shl 8 + HW[1];
wWidth := HW[2] Shl 8 + HW[3];
End Else
Begin
If Not (BD In [$01, $D0, $D1, $D2, $D3, $D4, $D5, $D6, $D7]) Then
Begin
FS.Read(Le,2);
WD := Le[0] Shl 8 + Le[1];
FS.Seek(WD - 2, 1);
FS.Read(BD, 1);
End Else BD := $FF;
End;
End;
End;
End;
Finally
FS.Free;
End;
End;