Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Delphi Bytes im Word drehen (https://www.delphipraxis.net/182889-bytes-im-word-drehen.html)

Helmi 24. Nov 2014 14:59

Bytes im Word drehen
 
Hallo,

ich steh grad auf der Leitung.

Ich lese mit folgenden Code die ersten 2 Bytes einer Datei (in diesem Falle von Bilddateien) aus
und prüfe somit um welches Format (BMP, JPG,PNG) es ist.

Nun sind aber die 2 Bytes im Word gegenüber der Datei vertauscht (wenn man sich die Datei mit
einem Hex-Editor anschaut).

Wie kann ich ganz einfach die zwei Bytes im Buffer drehen?

Oder anders gefragt, wie könnte man die ersten 2 Bytes "richtig" auslesen?

Delphi-Quellcode:
var
  FileHandle: Integer;
  Buffer   : Word;

begin
  FileHandle := FileOpen(Picture, fmOpenRead);
  FileSeek(FileHandle, 0, 0);
  FileRead(FileHandle, Buffer, 2);
  FileClose(FileHandle);

  case Buffer of
    $4D42: Result := pw_BMP;
    $D8FF: Result := pw_JPG;
    $5089: Result := pw_PNG;
  else
    Result := pw_None;
  end;

samso 24. Nov 2014 15:16

AW: Bytes im Word drehen
 
Swap -> http://docwiki.embarcadero.com/Libra...en/System.Swap

oder vielleicht auch

Delphi-Quellcode:
case Buffer of
     $424D: Result := pw_BMP;
     $FFD8: Result := pw_JPG;
     $8950: Result := pw_PNG;
   else
     Result := pw_None;
   end;

Uwe Raabe 24. Nov 2014 15:20

AW: Bytes im Word drehen
 
Die x86-Architektur speichert Integer und seine Derivate (so auch Word) im LSB-Format. Das bedeutet, daß das am wenigsten signifikate Byte (LSB) als erstes kommt. Somit wird die Byte-Sequenz $FF,$D8 als ein Word $D8FF interpretiert. Analog gilt das natürlich auch für größere Integer-Typen.

Du musst bei der Angabe der Word-Werte in der case-Anweisung dies berücksichtigen. Eine Bitmap-Datei beginnt z.B. mit der Byte-Sequenz $42, $4D (was übrigens den ASCII-Buchstaben "BM" entspricht). Wenn du diese zwei Bytes als Word interpretierst, dann wird das als $4D42 = 19778 eingelesen. Eigentlich musst du somit gar nichts an deinem Code ändern. Die case-Anweisung sollte funktionieren.

Der schöne Günther 24. Nov 2014 15:24

AW: Bytes im Word drehen
 
Ich musste neulich auch einmal die Endianess von einem Word ändern, habe mich aber vor System.Swap(..) gefürchtet: Die Doku spricht von Word (2Byte), die Signatur von einem Integer (4Byte).

Echte Delphi-Graurücken schütteln sich da wahrscheinlich das passende Assembler-Kommando aus dem Ärmel, aber ich habe mir (manch einer wird wohl lachen) den hier gemacht:

Delphi-Quellcode:
   TWordHelper = record helper for System.Word
      /// <summary>
      ///     Vertauscht beide Bytes
      /// </summary>
      public procedure flipEndianess();
   end;


procedure TWordHelper.flipEndianess();
var
   firstBytePtr, secondBytePtr: PByte;
   firstByteValue: Byte;
begin
   firstBytePtr := Addr(self);
   secondBytePtr := firstBytePtr + 1;

   firstByteValue := firstBytePtr^;
   firstBytePtr^ := secondBytePtr^;
   secondBytePtr^ := firstByteValue;
end;
Weil ich sonst einfach nichts besseres gefunden habe. Eigentlich sollte so etwas in den Helferklassen für simple Typen drinstecken. Finde ich.

hathor 24. Nov 2014 15:24

AW: Bytes im Word drehen
 
Warum Buffer:WORD, nimm Buffer:BYTE.
FileRead liest Byte-weise.

DeddyH 24. Nov 2014 15:32

AW: Bytes im Word drehen
 
Wenn man Word braucht, wieso dann Byte nehmen? Und wie ich die Hilfe verstehe, liest FileRead blockweise, deshalb der Count-Parameter.

Helmi 24. Nov 2014 15:33

AW: Bytes im Word drehen
 
Zitat:

Zitat von samso (Beitrag 1280920)

Danke - das hab ich gesucht (mir ist immer nur die Step7-Funktion eingefallen :-) )

Zitat:

Zitat von Uwe Raabe (Beitrag 1280921)
Eigentlich musst du somit gar nichts an deinem Code ändern. Die case-Anweisung sollte funktionieren.

Mein Code funktioniert auch. Nur was mich immer daran gestört hat, ist, dass ich in der Case-Anweisung die zwei Bytes "verdreht" gegenüber der Datei hinschreiben hab müssen.

Zitat:

Zitat von Der schöne Günther (Beitrag 1280922)
Ich musste neulich auch einmal die Endianess von einem Word ändern, habe mich aber vor System.Swap(..) gefürchtet: Die Doku spricht von Word (2Byte), die Signatur von einem Integer (4Byte).

Echte Delphi-Graurücken schütteln sich da wahrscheinlich das passende Assembler-Kommando aus dem Ärmel, aber ich habe mir (manch einer wird wohl lachen) den hier gemacht:

Delphi-Quellcode:
   TWordHelper = record helper for System.Word
      /// <summary>
      ///     Vertauscht beide Bytes
      /// </summary>
      public procedure flipEndianess();
   end;


procedure TWordHelper.flipEndianess();
var
   firstBytePtr, secondBytePtr: PByte;
   firstByteValue: Byte;
begin
   firstBytePtr := Addr(self);
   secondBytePtr := firstBytePtr + 1;

   firstByteValue := firstBytePtr^;
   firstBytePtr^ := secondBytePtr^;
   secondBytePtr^ := firstByteValue;
end;
Weil ich sonst einfach nichts besseres gefunden habe. Eigentlich sollte so etwas in den Helferklassen für simple Typen drinstecken. Finde ich.

Danke - aber swap reicht mir

Zitat:

Zitat von hathor (Beitrag 1280923)
Warum Buffer:WORD, nimm Buffer:BYTE.
FileRead liest Byte-weise.

Ich brauch aber zwei Bytes

Poelser 24. Nov 2014 15:49

AW: Bytes im Word drehen
 
Zitat:

Zitat von Der schöne Günther (Beitrag 1280922)
Echte Delphi-Graurücken schütteln sich da wahrscheinlich das passende Assembler-Kommando aus dem Ärmel

ROTFL, dann rück ich das Assemblerteil mal raus: ROR 8 oder ROL 8 auf das Word rotiert um 8 Bits links oder rechts rum, damit sind die Bytes getauscht.

CU, der Pølser

hathor 24. Nov 2014 16:10

AW: Bytes im Word drehen
 
Zitat:

Zitat von Helmi (Beitrag 1280925)
Ich brauch aber zwei Bytes

2 Bytes reichen nicht.

1. Sind die Bytes nicht immer am Anfang
2. können es auch mehr sein, z.B. 4 Bytes...

Helmi 24. Nov 2014 16:18

AW: Bytes im Word drehen
 
Zitat:

Zitat von hathor (Beitrag 1280928)
Zitat:

Zitat von Helmi (Beitrag 1280925)
Ich brauch aber zwei Bytes

2 Bytes reichen nicht.

1. Sind die Bytes nicht immer am Anfang
2. können es auch mehr sein, z.B. 4 Bytes...

also bislang hats immer ausgereicht und so funktioniert


Alle Zeitangaben in WEZ +1. Es ist jetzt 14:43 Uhr.
Seite 1 von 2  1 2      

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