Einzelnen Beitrag anzeigen

MicMic

Registriert seit: 26. Mai 2018
296 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#26

AW: GetJPGSize Funktion (wollen wir sie verbessern?)

  Alt 15. Feb 2020, 21:20
Das PDF von aboutvb hatte ich auch mal kurz überflogen aber alles nicht so einfach zu verstehen um es in Delphi umzusetzen.
Also ich kannte es schon. Trotzdem Danke für den Link. Versuche mich gerade daran nochmal.
Deine Funktion versuche ich erst mal zu ignorieren und will meine Funktion abändern. Einfach um alles besser zu verstehen.
Inzwischen habe ich meine Funktion ein wenig geändert. Funktioniert soweit abgesehen von einer Sache (die bei dir wohl auch noch nicht funktioniert), nämlich Hoch/Querformat. Bei Hochformat werden die Angaben vertauscht (in Breite steht die Höhe, in Höhe die Breite).

Hier mal mein neuer Code und schnell mal bissl Kommentare dazu:
Delphi-Quellcode:
Procedure GetJPGSize(sFile: String; Out WW, WH: DWord);
Var
  FS: TFileStream;
  BD: Byte;
  WD : Word;
  RL: LongInt;
  HW : Array[0..3] Of Byte;
  LE : Array[0..1] Of Byte;
Begin
  sFile := '\\?\'+SFile;
  WW := 0;
  WH := 0;
  FS := TFileStream.Create(sFile, fmShareDenyNone);
  Try

    // Erste 2 Bytes lesen
    RL := FS.Read(WD, 2);
    // Wenn FFD8 nicht vorhanden, dann RL auf 0 setzen
    If (Lo(WD) <> $FF) And (Hi(WD) <> $D8) Then RL := 0;

    If RL > 0 Then
    Begin

      // Nächstes Byte lesen. Ist (oder sollte) immer FF sein
      RL := FS.Read(BD, 1);

      While (BD = $FF) And (RL > 0) Do
      Begin
        // Nächstes Byte lesen
        RL := FS.Read(BD, 1);

        // Wenn alles außer FF, dann...
        If BD <> $FF Then
        Begin
          // Prüfen auf diese C0,C1 usw.
          If BD In [$C0,$C1,$C2] Then // <- kommt noch mehr dazu
          Begin
            // 3 Bytes weiter. Längenangabe (2 Bytes) sowie die Bit-Tiefe (1 Byte)
            // wird nicht benötigt
            FS.Seek(3,soFromCurrent);
            FS.Read(HW,4); // 4 Bytes (2 für Breite und 2 für Höhe)
            WH := HW[0] Shl 8 + HW[1];
            WW := HW[2] Shl 8 + HW[3];

            // ...
            // Hier muss noch was rein, wegen Hoch/Querformat
            // ...

            // Breite/Höhe gespeichert. Vielleicht ja noch mal prüfen? Jedenfalls hier Abbrechen
            Break;
          End Else
          Begin
            If BD<>$DA Then
            Begin
              FS.Read(Le,2); // 2 Bytes lesen (Längenangabe)
              WD := LE[0] Shl 8 + Le[1]; // Länge in Little Endian zurück (soll ja im JPG immer in BIG-Endian abgespeichert sein)
              FS.Seek(WD - 2, soFromCurrent); // Position zum nächsten Segment (-2 wegen 2 Byte-Längenangabe)
              FS.Read(BD, 1); // Erstes $FF lesen
            End Else Break; // <- DA gefunden, also fertig.
          End;
        End;
      End;
    End;
  Finally
    FS.Free;
  End;
End;
Bei aboutvb ist nun auf Seite 764 erst mal eine Tabelle (Tabelle 27.13) mit diesen C1,C2,C3 usw. Hier wurden die 3 (C4,C8,CC) auch weggelassen... also so, wie ich es bei Wikipedia las. Soweit so gut. In Tabelle 27.14 geht es dann weiter. Dort wird aber wieder (erste Zeile in der Tabelle) von FFDxH gesprochen. Auch weiter unten im Text...

"Wegen der geforderten Baseline DCT Komprimierung sollte die Signatur FFD0H auftreten."

Meinte der Autor hier nicht "FFC0H"?

In meinem Code jedenfalls überspringe ich 3 Bytes mit Seek.
Kommentar in meinem Code dort "3 Bytes weiter. Längenangabe (2 Bytes) sowie die Bit-Tiefe (1 Byte) wird nicht benötigt"

Es funktioniert jedenfalls so. Wenn ich mir die Tabelle 27.14 (aboutvb) betrachte, scheint dies ja so richtig zu sein. Abgesehen von der Angabe dort "FFD0H". Was wohl "FFC0H" sein sollte. Oder bringe ich was durcheinander?

Jedenfalls müsste ich dann wohl noch folgendes einfügen... bei meinem Kommentar (Hier muss noch was rein, wegen Hoch/Querformat) im Code:

1. 2 Byte überspringen
2. 1 Byte lesen und Werte prüfen.
3. ggf. Variablen für Breite/Höhe vertauschen

Laut Tabelle: Wert 0-3 vertikal und 4-7 horizontal müsste ich ermittelt bekommen.

Ich erreiche aber Werte von 17 (Querformat), mal 34 und auch mal 33 für Hochformat. Also so ganz klappt's noch nicht aber wohl fast.

Am Ende müsste man sich noch fragen, ob man die richtigen Werte vom Bild bekommt. In JPG soll man ja auch kleinere Vorschaubilder speichern können. 1 Vorschaubild? Mehrere? Wohl mehrere. Ich denke damit sind diese "ID x. Komponenten" gemeint. Im PDF (aboutvb) ist ja schon von "ID 3. Komponente" die Rede. Wobei dort in der Tabelle (27.14) nicht mehr von Bildgrößen zu lesen ist, sondern nur noch (pro Komponente) von Hoch/Querformat (Abtastfaktor) und einer Nummer von einer Quantisierungstabelle. Was auch immer das nun wieder ist Aber wenn es kleinere Vorschaubilder geben kann, gibt es sicherlich auch für diese ganze 4 Bytes für das Abfragen der Breite/Höhe. Hoffentlich ist das 1. immer das Originalbild. Alles was danach kommt (ob nun mit Vorschaubilder oder nicht) könnte ja einem dann egal sein. Zumindest für dieses Thema (Ermitteln der JPG Bildgröße).
  Mit Zitat antworten Zitat