Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Delphi Header aus PNG laden (https://www.delphipraxis.net/192148-header-aus-png-laden.html)

EWeiss 23. Mär 2017 01:08


Header aus PNG laden
 
Bin mir jetzt nicht sicher ob das so ok ist.
Es wird zwar True zurückgegeben aber den Headern habe ich deshalb trotzdem nicht.
Wie bekomme ich den?

Delphi-Quellcode:
  AniHeader = Record
    Frame: WORD;
    Width: WORD;
    Height: WORD;
    Speed: WORD;
    offset: dword;
    reserved: dword;
    Sign: dword;
  end;
Delphi-Quellcode:
function TAnimatePng.GetPngAnimation(wsFile: string; var anih: TAniHeader): Bool;
var
  ByteArray: array of byte;
  FileStream: TFileStream;
  IntI: Integer;
begin
  Result := False;
  try
    FileStream := TFilestream.Create(wsFile ,fmopenread or fmShareDenyNone);
    SetLength(ByteArray, FileStream.Size);
    FileStream.Read(ByteArray[0], Length(ByteArray));
  finally
    FileStream.Free;
  end;

  for IntI := Low(ByteArray) to High(ByteArray) do
  begin
    if (ByteArray[IntI] * 4) = StrToInt('ANIM') then
      Result := True
  end;

end;
Falls nicht bitte sagen was falsch läuft.

gruss

Zacherl 23. Mär 2017 01:29

AW: Header aus PNG laden
 
Du liest den Header ja nirgends aus bzw. weißt deinem
Delphi-Quellcode:
var
Parameter niemals einen Wert zu.

Außerdem:
Delphi-Quellcode:
for IntI := Low(ByteArray) to High(ByteArray) do
  begin
    if (ByteArray[IntI] * 4) = StrToInt('ANIM') then
      Result := True
  end;
:?:

Was soll dieser Code bewirken?

Ich kann nur sagen, dass
Delphi-Quellcode:
StrToInt('ANIM')
schonmal definitiv eine Exception schmeißen wird.

EWeiss 23. Mär 2017 01:31

AW: Header aus PNG laden
 
Zitat:

Zitat von Zacherl (Beitrag 1365159)
Du liest den Header ja nirgends aus bzw. weißt deinem
Delphi-Quellcode:
var
Parameter niemals einen Wert zu.

Außerdem:
Delphi-Quellcode:
for IntI := Low(ByteArray) to High(ByteArray) do
  begin
    if (ByteArray[IntI] * 4) = StrToInt('ANIM') then
      Result := True
  end;
:?:

Was soll dieser Code bewirken?

Ich kann nur sagen, dass
Delphi-Quellcode:
StrToInt('ANIM')
schonmal definitiv eine Exception schmeißen wird.

Deswegen frage ich ja was falsch ist. ;)
Nein ein exeption wird nicht geworfen es kommt ein true zurück.

Wie komme ich denn an den Header und kann nach dem anih.Sign := ANIM suchen?
Die Daten sollten sich ja im ByteArray befinden.


gruss

Zacherl 23. Mär 2017 01:33

AW: Header aus PNG laden
 
Zitat:

Zitat von EWeiss (Beitrag 1365160)
Nein ein exeption wird nicht geworfen es kommt ein true zurück.

Dann läuft irgendwas gewaltig schief, denn:
Zitat:

---------------------------
Project1
---------------------------
'ANIM' ist kein gültiger Integerwert.
---------------------------
OK
---------------------------
Zitat:

Zitat von EWeiss (Beitrag 1365160)
Wie komme ich denn an den Header und kann nach dem anih.Sign := ANIM suchen?

Der Header steht genau in der von dir modellierten Form (TAniHeader) direkt am Anfang der Datei?

EWeiss 23. Mär 2017 01:35

AW: Header aus PNG laden
 
So wie der Code oben abgebildet wirft er mir kein Exeption glaube mir das Bitte.
D2010.

Zitat:

Der Header steht genau in der von dir modellierten Form (TAniHeader) direkt am Anfang der Datei?
Nein ganz hinten.

Am Anfang steht "IHDR"
Am Ende steht "ANIM"

Der Header ist so korrekt.

gruss

Zacherl 23. Mär 2017 01:42

AW: Header aus PNG laden
 
Zitat:

Zitat von EWeiss (Beitrag 1365162)
So wie der Code oben abgebildet wirft er mir kein Exeption glaube mir das Bitte.
D2010.

In meiner Erinnerung hat selbst Delphi 7 beim Aufruf von
Delphi-Quellcode:
StrToInt
mit ungültiger Zahl schon eine Exception geschmissen. So oder so ist "ANIM" auf jeden Fall keine Zahl, weshalb
Delphi-Quellcode:
StrToInt
nicht funktionieren kann und in irgendeiner Form fehlschlagen wird.

Aber nur zur Sicherheit:
Der Code wird wirklich ausgeführt und du hast auch keinen Exception Handler um den Aufruf, der die Exception ggfls. abfangen könnte?

Zitat:

Zitat von EWeiss (Beitrag 1365162)
Zitat:

Der Header steht genau in der von dir modellierten Form (TAniHeader) direkt am Anfang der Datei?
Nein ganz hinten

Dann kannst du einfach mit
Delphi-Quellcode:
TFileStream.Seek
ans Ende der Datei abzüglich
Delphi-Quellcode:
SizeOf(TAniHeader)
springen und den Header direkt mit
Delphi-Quellcode:
TFileStream.Read(anih, SizeOf(anih))
auslesen.

EWeiss 23. Mär 2017 01:45

AW: Header aus PNG laden
 
Zitat:

Aber nur zur Sicherheit:
Der Code wird wirklich ausgeführt und du hast auch keinen Exception Handler um den Aufruf, der die Exception ggfls. abfangen könnte?
Ich habe mal MadExcept angeworfen und nein so wie du am bild sehen kann gibt der Compiler True zurück ohne wenn und aber ;)
Aber ich glaube dir das es falsch ist.

Zitat:

Dann kannst du einfach mit TFileStream.Seek ans Ende der Datei abzüglich SizeOf(TAniHeader) springen und den Header direkt mit TFileStream.Read(anih, SizeOf(anih)) auslesen.
Sorry kannst du mir das am Code verbildlichen?

gruss

Zacherl 23. Mär 2017 01:48

AW: Header aus PNG laden
 
Zitat:

Zitat von EWeiss (Beitrag 1365164)
Zitat:

Aber nur zur Sicherheit:
Der Code wird wirklich ausgeführt und du hast auch keinen Exception Handler um den Aufruf, der die Exception ggfls. abfangen könnte?
Ich habe mal MadExcept angeworfen und nein so wie du am bild sehen kann gibt der Compiler True zurück ohne wenn und aber ;)

Das ist interessant :shock: Was gibt
Delphi-Quellcode:
StrToInt('ANIM')
denn für einen Wert zurück? Das ist jetzt mal spannend herauszufinden.

EWeiss 23. Mär 2017 01:50

AW: Header aus PNG laden
 
Zitat:

Zitat von Zacherl (Beitrag 1365165)
Zitat:

Zitat von EWeiss (Beitrag 1365164)
Zitat:

Aber nur zur Sicherheit:
Der Code wird wirklich ausgeführt und du hast auch keinen Exception Handler um den Aufruf, der die Exception ggfls. abfangen könnte?
Ich habe mal MadExcept angeworfen und nein so wie du am bild sehen kann gibt der Compiler True zurück ohne wenn und aber ;)

Das ist interessant :shock: Was gibt
Delphi-Quellcode:
StrToInt('ANIM')
denn für einen Wert zurück? Das ist jetzt mal spannend herauszufinden.

Er durchläuft das Array bis 8 und schaltet dann auf true.
Ausgeben tut er sonst nichts.

Aber wie gesagt es kann nicht richtig sein auch wenn das Ergebnis true ist.
So komme ich nicht an den Header.

Das ist was ich sehe wenn IntI 8 ist.


gruss

Zacherl 23. Mär 2017 01:53

AW: Header aus PNG laden
 
Zitat:

Zitat von EWeiss (Beitrag 1365166)
Zitat:

Zitat von Zacherl (Beitrag 1365165)
Zitat:

Zitat von EWeiss (Beitrag 1365164)
Zitat:

Aber nur zur Sicherheit:
Der Code wird wirklich ausgeführt und du hast auch keinen Exception Handler um den Aufruf, der die Exception ggfls. abfangen könnte?
Ich habe mal MadExcept angeworfen und nein so wie du am bild sehen kann gibt der Compiler True zurück ohne wenn und aber ;)

Das ist interessant :shock: Was gibt
Delphi-Quellcode:
StrToInt('ANIM')
denn für einen Wert zurück? Das ist jetzt mal spannend herauszufinden.

Er durchläuft das Array bis 8 und schaltet dann auf true.
Ausgeben tut er sonst nichts.

Was passiert denn, wenn du mal ganz am Anfang der Funktion testweise ein
Delphi-Quellcode:
ShowMessage(IntToStr(StrToInt('ANIM')))
machst? Würde mich mal interessieren.

Zitat:

Zitat von EWeiss (Beitrag 1365166)
Aber wie gesagt es kann nicht richtig sein auch wenn das Ergebnis true ist.
So komme ich nicht an den Header.

Wenn der Header tatsächlich immer am Dateiende ist, kannst du ihn ganz einfach so auslesen und dir sowohl das Byte-Array, als auch die komische Schleife sparen:
Delphi-Quellcode:
FileStream := TFilestream.Create(wsFile ,fmopenread or fmShareDenyNone);
  try
    FileStream.Seek(-SizeOf(TAniHeader), soEnd);
    FileStream.Read(anih, SizeOf(anih));
  finally
    FileStream.Free;
  end;

EWeiss 23. Mär 2017 01:56

AW: Header aus PNG laden
 
Zitat:

Was passiert denn, wenn du mal ganz am Anfang der Funktion testweise ein ShowMessage(IntToStr(StrToInt('ANIM'))) machst? Würde mich mal interessieren.
Klar mache ich gerne.

Da steht 0.
Klasse jetzt habe ich den Header.
Jetzt muss ich nur noch wissen ob ANIM existiert. Sign ist nur ein Zahlenwert.

Noch ein Bild ;)

gruss

Zacherl 23. Mär 2017 02:02

AW: Header aus PNG laden
 
Zitat:

Zitat von EWeiss (Beitrag 1365168)
Da steht 0.

Sehr seltsam. Entweder ein Bug in D2010 oder irgendeine seltene Einstellung, die du vorgenommen hast. Naja egal, für dein Problem ja nicht weiter relevant jetzt.

Luckie 23. Mär 2017 02:02

AW: Header aus PNG laden
 
Liste der Anhänge anzeigen (Anzahl: 1)
Das
Delphi-Quellcode:
ShowMessage(IntToStr(StrToInt('ANIM')));
wirft definitiv eine Exception. Ich habe die Vermutung, dass er die Schleife gar nicht durchläuft und so an die Stelle gar nicht erst kommt.

EWeiss 23. Mär 2017 02:07

AW: Header aus PNG laden
 
Zitat:

Zitat von Luckie (Beitrag 1365170)
Das
Delphi-Quellcode:
ShowMessage(IntToStr(StrToInt('ANIM')));
wirft definitiv eine Exception. Ich habe die Vermutung, dass er die Schleife gar nicht durchläuft und so an die Stelle gar nicht erst kommt.

Delphi-Quellcode:
function TAnimatePng.GetPngAnimation(wsFile: string; var anih: TAniHeader): Bool;
var
  ByteArray: array of byte;
  FileStream: TFileStream;
  IntI: Integer;
begin
  Result := False;
  ShowMessage(IntToStr(StrToInt('ANIM')));

  try
    FileStream := TFilestream.Create(wsFile ,fmopenread or fmShareDenyNone);
    FileStream.Seek(-SizeOf(TAniHeader), soEnd);
    FileStream.Read(anih, SizeOf(anih));
  finally
    FileStream.Free;
  end;

end;
Wirft kein Exception
Das ist Fakt.

Sign ist nur ein Zahlenwert.
Wie bekomme ich den jetzt als String?

gruss

Zacherl 23. Mär 2017 02:09

AW: Header aus PNG laden
 
Zitat:

Zitat von EWeiss (Beitrag 1365168)
Jetzt muss ich nur noch wissen ob ANIM existiert. Sign ist nur ein Zahlenwert.

Ob du 'ANIM' jetzt als 4-stelligen ANSI-String, oder als 4-Byte DWORD vorliegen hast, macht im Grunde keinen Unterschied. Am Einfachsten ist es, wenn du
Delphi-Quellcode:
anih.Sign
einfach mit dem korrekten Zahlenwert (0x4D494E41) vergleichst.

Zitat:

Zitat von Luckie (Beitrag 1365170)
Das
Delphi-Quellcode:
ShowMessage(IntToStr(StrToInt('ANIM')));
wirft definitiv eine Exception. Ich habe die Vermutung, dass er die Schleife gar nicht durchläuft und so an die Stelle gar nicht erst kommt.

Deshalb hatte ich ja gefragt, ob er mal diesen Testcode mit der MessageBox direkt an den Anfang der Funktion packen kann. Ich bin auch der Meinung, dass eine Exception kommen müsste, aber anscheinend gibt
Delphi-Quellcode:
StrToInt
bei seiner Konfiguration einfach nur still und heimlich 0 zurück :pale: Kann ich mir auch nicht erklären.

@Emil:
Kannst du den MessageBox Code mal noch in einem komplett leeren Projekt testen? Vielleicht hast du an irgendeiner Stelle davor eine Memory Corruption verursacht, die jetzt den Programmfluss in komischer Weise stört.

Luckie 23. Mär 2017 02:11

AW: Header aus PNG laden
 
Dann muss er an den Einstellungen zu den Exceptions was verändert haben. Aber ich dachte, die würden sich nur beim Debuggen auswirken und nicht in der Exe.

EWeiss 23. Mär 2017 02:12

AW: Header aus PNG laden
 
Zitat:

Ob du 'ANIM' jetzt als 4-stelligen ANSI-String, oder als 4-Byte DWORD vorliegen hast, macht im Grunde keinen Unterschied. Am Einfachsten ist es, wenn du anih.Sign einfach mit dem korrekten Zahlenwert (0x4D494E41) vergleichst.
Bitte, Beispiel ;) Muss da noch lernen.
Dann ist das soweit fertig ...

Danke für deine Mühe

Zu dem anderen Problem siehe das Pic was ich noch hochgeladen habe.

gruss

EWeiss 23. Mär 2017 02:12

AW: Header aus PNG laden
 
Zitat:

@Emil:
Kannst du den MessageBox Code mal noch in einem komplett leeren Projekt testen? Vielleicht hast du an irgendeiner Stelle davor eine Memory Corruption verursacht, die jetzt den Programmfluss in komischer Weise stört.
Klar kann ich machen.

Edit:
Leeres Projekt kommt ein Error.
In FormCreate

Sehr seltsam.

gruss

Zacherl 23. Mär 2017 02:13

AW: Header aus PNG laden
 
Zitat:

Zitat von EWeiss (Beitrag 1365174)
Zitat:

Ob du 'ANIM' jetzt als 4-stelligen ANSI-String, oder als 4-Byte DWORD vorliegen hast, macht im Grunde keinen Unterschied. Am Einfachsten ist es, wenn du anih.Sign einfach mit dem korrekten Zahlenwert (0x4D494E41) vergleichst.
Bitte, Beispiel ;) Muss da noch lernen.

Ganz simpel:
Delphi-Quellcode:
if (anih.Sign = $4D494E41) then
begin
  // Sign = 'ANIM'
end
Oder alternativ kannst du Sign auch in deinem Record direkt als
Delphi-Quellcode:
array[0..3] of AnsiChar
deklarieren und dann die einzelnen Zeichen vergleichen. Ist vermutlich minimal langsamer, aber dafür besser verständlich.

Zitat:

Zitat von Luckie (Beitrag 1365173)
Dann muss er an den Einstellungen zu den Exceptions was verändert haben. Aber ich dachte, die würden sich nur beim Debuggen auswirken und nicht in der Exe.

Die Idee hatte ich auch grade und habe es getestet: Wirkt sich wie erwartet nur auf den Debugger aus. Die MessageBox mit der Exception wird vom Programm selbst aber nach wie vor angezeigt.

Luckie 23. Mär 2017 02:15

AW: Header aus PNG laden
 
Jetzt bin ich auf das leer Projekt gespannt.

Zacherl 23. Mär 2017 02:17

AW: Header aus PNG laden
 
Zitat:

Zitat von EWeiss (Beitrag 1365175)
Leeres Projekt kommt ein Error.
In FormCreate

Sehr seltsam

Ja das habe ich befürchtet. Dann hat dein richtiges Projekt irgendwo eine Memory Corruption ausgelöst, die jetzt für unvorhersehbare Seiteneffekte sorgt.

EWeiss 23. Mär 2017 02:19

AW: Header aus PNG laden
 
Zitat:

Zitat von Zacherl (Beitrag 1365176)
Zitat:

Zitat von EWeiss (Beitrag 1365174)
Zitat:

Ob du 'ANIM' jetzt als 4-stelligen ANSI-String, oder als 4-Byte DWORD vorliegen hast, macht im Grunde keinen Unterschied. Am Einfachsten ist es, wenn du anih.Sign einfach mit dem korrekten Zahlenwert (0x4D494E41) vergleichst.
Bitte, Beispiel ;) Muss da noch lernen.

Ganz simpel:
Delphi-Quellcode:
if (anih.Sign = $4D494E41) then
begin
  // Sign = 'ANIM'
end
Oder alternativ kannst du Sign auch in deinem Record direkt als
Delphi-Quellcode:
array[0..3] of AnsiChar
deklarieren und dann die einzelnen Zeichen vergleichen. Ist vermutlich minimal langsamer, aber dafür besser verständlich.

Zitat:

Zitat von Luckie (Beitrag 1365173)
Dann muss er an den Einstellungen zu den Exceptions was verändert haben. Aber ich dachte, die würden sich nur beim Debuggen auswirken und nicht in der Exe.

Die Idee hatte ich auch grade und habe es getestet: Wirkt sich wie erwartet nur auf den Debugger aus. Die MessageBox mit der Exception wird vom Programm selbst aber nach wie vor angezeigt.

Nur wie weiß ich jetzt das anih.Sign diesen wert $4D494E41 hat.
Er steht zwar bei Sign aber habe ich eine Garantie das es immer so ist?

Zitat:

Dann hat dein richtiges Projekt irgendwo eine Memory Corruption ausgelöst, die jetzt für unvorhersehbare Seiteneffekte sorgt.
Oder aber es liegt an NOnVCL ?


gruss

Luckie 23. Mär 2017 02:20

AW: Header aus PNG laden
 
Das müsste in der Doku zu dem Format stehen.

Das hat mit VCL oder NonVCL nichts zu tun. Du zerschießt dir irgendwo deinen Speichern.

EWeiss 23. Mär 2017 02:21

AW: Header aus PNG laden
 
Zitat:

Zitat von Luckie (Beitrag 1365181)
Das müsste in der Doku zu dem Format stehen.

Was ob das NonVcl bedingt ist. ?

Zitat:

Das hat mit VCL oder NonVCL nichts zu tun. Du zerschießt dir irgendwo deinen Speichern.
Hmm wie soll man so was finden.
Seltsam das nicht mal madExcept darauf anspringt.

gruss

Luckie 23. Mär 2017 02:24

AW: Header aus PNG laden
 
Das mit der Doku bezog sich auf die Frage, ob der Wert immer der gleiche ist.

Das seltsame verhalten deines Programms, welches keine Exception wirft, obwohl es es tun und das daran liegt, dass du dir irgendwo deinen Speicher zerschossen hat, hat nichts mit VCL oder NonVCL zu tun.

Zacherl 23. Mär 2017 02:26

AW: Header aus PNG laden
 
Ob im Sign Feld immer 'ANIM' steht, kann dir wirklich nur die Doku sagen. Wenn es dir um den Zahlenwert geht, dann ja, der bleibt gleich. Es ist nur eine Frage der Darstellung:
Code:
$4D494E41 = $41 $4E $49 $4D = 'A' 'N' 'I' 'M'
Erst als 4-Byte Integer bzw. DWORD, dann als 4 einzelne Bytes und dann als 4 einzelne AnsiChars.

Luckie 23. Mär 2017 02:26

AW: Header aus PNG laden
 
Madexcept findet auch keine Code mit dem du dir deinen Speicher zerschießt. Ich würde erst mal alle Warnungen beim Kompilieren beseitigen, wenn denn welche auftauchen.

EWeiss 23. Mär 2017 02:29

AW: Header aus PNG laden
 
Zitat:

Zitat von Zacherl (Beitrag 1365184)
Ob im Sign Feld immer 'ANIM' steht, kann dir wirklich nur die Doku sagen. Wenn es dir um den Zahlenwert geht, dann ja, der bleibt gleich. Es ist nur eine Frage der Darstellung:
Code:
$4D494E41 = $41 $4E $49 $4D = 'A' 'N' 'I' 'M'
Erst als 4-Byte Integer bzw. DWORD, dann als 4 einzelne Bytes und dann als 4 einzelne AnsiChars.

Super danke ;) für deine Hilfe.
Dann ist das erledigt.

Hätte ich auch drauf kommen müssen das es HEX werte sind ;)
Ist schon spät. LOL

Zitat:

Ich würde erst mal alle Warnungen beim Kompilieren beseitigen, wenn denn welche auftauchen.
Werde ich machen obwohl eigentlich alles eigenschaltet und behandelt wird.


gruss

Zacherl 23. Mär 2017 02:32

AW: Header aus PNG laden
 
Zitat:

Zitat von EWeiss (Beitrag 1365182)
Hmm wie soll man so was finden.
Seltsam das nicht mal madExcept darauf anspringt

Ne, das ist nicht weiter seltsam. Zuerst solltest du mal die Bereichsüberprüfungen anschmeißen. Ich weiß zwar nicht, ob Delphi auch Bereichsüberschreitungen mitbekommt, die z.b. per
Delphi-Quellcode:
CopyMemory
ausgelöst wurden, aber einen Versuch ist es Wert.

Luckie 23. Mär 2017 02:32

AW: Header aus PNG laden
 
Dein Code kompiliert ohne Warnungen? Das meinte ich.

EWeiss 23. Mär 2017 02:35

AW: Header aus PNG laden
 
Zitat:

Zitat von Zacherl (Beitrag 1365187)
Zitat:

Zitat von EWeiss (Beitrag 1365182)
Hmm wie soll man so was finden.
Seltsam das nicht mal madExcept darauf anspringt

Ne, das ist nicht weiter seltsam. Zuerst solltest du mal die Bereichsüberprüfungen anschmeißen. Ich weiß zwar nicht, ob Delphi auch Bereichsüberschreitungen mitbekommt, die z.b. per
Delphi-Quellcode:
CopyMemory
ausgelöst wurden, aber einen Versuch ist es Wert.

Ja das ist ja was ich meine.
Ich habe alles angeschaltet.

gruss


Alle Zeitangaben in WEZ +1. Es ist jetzt 22:44 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz