Behandlung vermutlich nicht-konformer EXIF Metadaten mit "fpExif"

Rund um die LCL und andere Komponenten
Antworten
Benutzeravatar
h-elsner
Lazarusforum e. V.
Beiträge: 259
Registriert: Di 24. Jul 2012, 15:42
OS, Lazarus, FPC: LINUX Mint21.1, Win10, Lazarus 2.2.4, FPC3.2.2
CPU-Target: X86-64; arm 32bit
Wohnort: Illertissen
Kontaktdaten:

Behandlung vermutlich nicht-konformer EXIF Metadaten mit "fpExif"

Beitrag von h-elsner »

Die Komponente "fpExif" habe ich nun in mehreren Projekten im Einsatz. Dies funktioniert prima. Vielen Dank an die Entwickler.

Jetzt bin ich allerdings auf zwei Probleme gestoßen bei Bilder von Kameras der Firma Yuneec. Diese Bilder möchte ich mit Geodaten (Koordinaten und Höhe) nachrüsten.

1. Problem:
Die Metadaten enthalten Segmente mit DataType=0. Dies führt bei aImgInfo.LoadFromFile zum Fehler rsIncorrectTagType und man kann die restlichen EXIF Daten nicht lesen.
Ich habe in fpeExifReadWrite den Fehleraussprung bei ifdRec.DataType=0; einfach übersprungen. Dann funktioniert zumindest das Lesen der weiteren Daten ohne (sichtbare) Probleme.
Meine Frage ist, welche Konsequenzen das wirklich hat, denn die überschaue ich mangels Kenntnisse nicht wirklich.

Code: Alles auswählen

in file "fpeExifReadWrite", procedure TBasicExifReader.ReadIFD(AStream: TStream; AParent: TTagID);

  //   File fpeExifReadWrite: Skip TagType 0 from Yuneec cam CGO3

    [b]if ifdRec.DataType<>0 then[/b]             // No error handling in case TagType=0

    if not (ifdRec.DataType in [1..ord(High(TTagType))]) then begin
      Error(Format(rsIncorrectTagType, [ifdRec.DataType, i, ifdRec.TagID, FImgInfo.Filename]));
      exit;
    end;
    ....
2. Problem:
Einige Bilder enthalten Segmente, die nach den Daten mit 00-Bytes aufgefüllt sind, warum auch immer. Auch bricht das Lesen Schreiben mit Fehler ab, weil nach der Payload-Länge natürlich nicht der nächste korrekte headerKey kommt, sondern 0.
Beholfen habe ich mir damit, dass ich die Nullen überspringe bis zum nächsten headerKey.
Auch hier wieder die Frage, ob ich mit unerwarteten Effekten rechnen muss oder ob das ein gangbarer Weg ist. Bei meinen Tests schien es OK.

Code: Alles auswählen


In "fpemetadata.pas", procedure TImgInfo.MergeToJpegStream(AInputStream, AOutputStream: TStream);

  // In some pictures the space between segments is filled with $00 (patch 11/2020)
    if header.Key = 0 then
      repeat                                //skip unnecessary $00
        inc(savedPos);
        AInputStream.Position := savedPos;  // Read next byte
        n := AInputStream.Read(header{%H-}, SizeOf(header));
        if n <> Sizeof(header) then
          Error(rsIncompleteJpegSegmentHeader);
      until header.Key <> 0;                // something else, hopefully a new segment
  --------------------------------------------------------------------------------
    if header.Key <> $FF then
      Error(rsJpegSegmentMarkerExpected);
    header.Size := BEToN(header.Size);
 ....

Die irregulären Segmente werden bei Schreiben ind die EXIF Daten nicht geschrieben, aber damit kann ich leben.

Gruß HE
Zuletzt geändert von h-elsner am So 17. Jan 2021, 13:21, insgesamt 3-mal geändert.

wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: Behandlung vermutlich nicht-konformer EXIF Metadaten mit "fpExif"

Beitrag von wp_xyz »

Kannst du mir ein Bild dieser Kamera zur Verfügung stellen? Am besten durch direkten Upload im Forum (evtl vorher zippen wenn die Forumsoftware die Dateiendung nicht mag), durch Link zu einer Cloud oder durch E-Mail-Anhang (meine E-Mail-Adresse per PM).

Benutzeravatar
h-elsner
Lazarusforum e. V.
Beiträge: 259
Registriert: Di 24. Jul 2012, 15:42
OS, Lazarus, FPC: LINUX Mint21.1, Win10, Lazarus 2.2.4, FPC3.2.2
CPU-Target: X86-64; arm 32bit
Wohnort: Illertissen
Kontaktdaten:

Re: Behandlung vermutlich nicht-konformer EXIF Metadaten mit "fpExif"

Beitrag von h-elsner »

Wie immer sauschnell. Danke.
Die Datei ist zu groß für hier, also nimm bitte diesen Link:
https://1drv.ms/u/s!Au__y3NGLbYEjWZotQm ... h?e=noEbWg

Gruß HE

wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: Behandlung vermutlich nicht-konformer EXIF Metadaten mit "fpExif"

Beitrag von wp_xyz »

Danke. Das bestätigt mal wieder mein Vorurteil, dass Hardware-Hersteller die Finger von Software lassen sollten.

Probier mal die aktuelle Version auf CCR aus. Ich hab's etwas anders gelöst als du. Nachdem ein Eintrag im IFD ("Image file directory") immer 12 Byte lang ist (siehe TIFDRecord), springe ich bei einem Leereintrag (d.h. wenn alle Felder des Record auf Null stehen) 12 Byte weiter an den Anfang des nächsten IFDRecord, bis die Anzahl der im IFD-Header eingetragenen Records abgeklappert ist. Ich könnte mir vorstellen, dass der Werkstudent, der das für YUNEEC geschrieben hat, einen EXIF-Eintrag löschen möchte, indem er ihn einfach mit Null überschreibt, anstatt die komplette EXIF-Struktur neu aufzubauen. Macht weniger Arbeit, vor allem wenn der Arbeitgeber zu wenig zahlt... (OK - vielleicht bin ich da jetzt einfach zu böse, und das ganze steht irgendwo in der EXIF-Spezifikation).

Ich glaube nicht, dass die Änderung eine Auswirkung irgendwo hat. Selbst wenn irgendwo in der Mitte ein solcher Null-Record gefunden wird, werden die nachfolgenden Records noch korrekt gelesen.

Benutzeravatar
h-elsner
Lazarusforum e. V.
Beiträge: 259
Registriert: Di 24. Jul 2012, 15:42
OS, Lazarus, FPC: LINUX Mint21.1, Win10, Lazarus 2.2.4, FPC3.2.2
CPU-Target: X86-64; arm 32bit
Wohnort: Illertissen
Kontaktdaten:

Re: Behandlung vermutlich nicht-konformer EXIF Metadaten mit "fpExif"

Beitrag von h-elsner »

Ja, mit Firmware schreiben haben die es nicht so. Da finde selbst ich noch Flüchtigkeitsfehler und manchmal fragt man sich, was das soll. Zumindest Problem No 1 haben sie bei den nächsten Kameratypen behoben. Dafür aber Problem 2 eingebaut.

Und die Firma stellt(e) auch manntragende Elektroflugzeuge her. Ob ich da einsteigen würde....?

Danke für die schnelle Analyse. Aber was sit CCR? Kenne ich nur als (gute) Rockband.

Gruß HE

Edit: Ahh, Code and Component Repository! Jetzt muss ich nur noch herausfinden, wie ich da downloade. Lass mich mal machen - so lernt man am schnellsten ;-).

Benutzeravatar
h-elsner
Lazarusforum e. V.
Beiträge: 259
Registriert: Di 24. Jul 2012, 15:42
OS, Lazarus, FPC: LINUX Mint21.1, Win10, Lazarus 2.2.4, FPC3.2.2
CPU-Target: X86-64; arm 32bit
Wohnort: Illertissen
Kontaktdaten:

Re: Behandlung vermutlich nicht-konformer EXIF Metadaten mit "fpExif"

Beitrag von h-elsner »

Ich habe den Patch nun mit Bildern von 5 verschiedenen Kameras geprüft (4 x Yuneec und 1 x Panasonic). Bei allen läuft das Prima durch. Ich kann auf die Schnelle keine Probleme erkennen.
Problem 1 damit gelöst. Vielen Dank!

Problem 2 tritt beim Schreiben auf, nicht beim Lesen. Sorry für den Fehler oben. Die Fehlermeldung lautet:
"Defective JPEG structure: Segment marker ($FF) expected."

Ich hatte den Patch in fpeexifreadwrite.pas mit und ohne meine Änderung in fpemetadata.pas getestet.

Gruß HE

wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: Behandlung vermutlich nicht-konformer EXIF Metadaten mit "fpExif"

Beitrag von wp_xyz »

Der folgende Code schreibt ein Feld UserComment in die EXIF-Daten. Die erzeugte Datei ist einwandfrei lesbar, sowohl mit meinem MetaDataViewer (in den Beispielen von fpExif) als auch mit dem "offiziellen" EXIFTool, denn die fehlerhafte Stelle ist beim Lesen ja überspringen worden und die Schreibroutine zählt auch die Zahl der Tags neu.

Ich denke, du musst deinen Code zeigen.

Code: Alles auswählen

program test;

{$mode objfpc}{$H+}

uses
  Classes,
  fpeMetaData, fpeTags;

var
  imgInfo: TImgInfo;
  tag: TTag;

begin
  imgInfo := TImgInfo.Create;
  try
    // Read file
    imgInfo.LoadFromFile('YUN00003.jpg');

    // Check for EXIF
    if imgInfo.HasExif then begin
      // Add user comment
      tag := imgInfo.ExifData.TagByName['UserComment'];
      if tag = nil then
        tag := imgInfo.ExifData.AddTagByName('UserComment');
      tag.AsString := 'This is my favorite photo.';
      // Save to file
      imgInfo.SaveToFile('edited_image.jpg');
    end
    else
      WriteLn('No EXIF data in this file.');

  finally
    imgInfo.Free;
  end;

  WriteLn;
  WriteLn('Press ENTER to quit...');
  ReadLn;

end.     

Benutzeravatar
h-elsner
Lazarusforum e. V.
Beiträge: 259
Registriert: Di 24. Jul 2012, 15:42
OS, Lazarus, FPC: LINUX Mint21.1, Win10, Lazarus 2.2.4, FPC3.2.2
CPU-Target: X86-64; arm 32bit
Wohnort: Illertissen
Kontaktdaten:

Re: Behandlung vermutlich nicht-konformer EXIF Metadaten mit "fpExif"

Beitrag von h-elsner »

Ich habe mich unklar ausgedrückt. Mit deinem Patch [r7964] geht Lesen und Schreiben bei CGO3 Bildern. Problem 1 gelöst.

Problem 2 tritt nur beim Schreiben auf, wenn XMP-Daten in den Metadaten drin sind, speziell bei der CGO3+ Kamera.

Hier mein Testprogramm, wo ich die Routinen teste, die ich in den 'richtigen' Projekten benutze. Ist etwas wirr. Man muss erst ein Bild lesen und kann dann erst schreiben (sprich der Dateiname muss bekannt sein).
fpEXIF_No2.zip
(497.93 KiB) 69-mal heruntergeladen
Test: Datei YUN00001.jpg laden. Dann Write drücken.
Bei mir kommt:
screenshot.png
screenshot.png (37.22 KiB) 1946 mal betrachtet
Gruß HE

wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: Behandlung vermutlich nicht-konformer EXIF Metadaten mit "fpExif"

Beitrag von wp_xyz »

Verstanden und behoben.

Ich verstehe nun, warum du die Dateien YUN00001.jpg und YUN00002.jpg mitgeliefert hast. Wofür ist dann YUN00003.jpg?

Ich habe dabei gelernt, dass $FFE1 sowohl für EXIF als auch XMP Metadaten als Kennung verwendet wird (womit verbringen die Normungskommittees eigentlich immer ihre Zeit?). Da ich angenommen hatte, die Marker kömen nur einmal vor, habe ich die XMP nicht gelesen und entsprechend auch nicht geschrieben. fpExif ist nun dahingehend erweitert, dass XMP eingelesen und 1:1 in die Zieldatei zurückgeschrieben wird. Auf lange Sicht sollte man natürlich XMP genauso über fpExif ansprechen können wie EXIF und IPTC.

Benutzeravatar
h-elsner
Lazarusforum e. V.
Beiträge: 259
Registriert: Di 24. Jul 2012, 15:42
OS, Lazarus, FPC: LINUX Mint21.1, Win10, Lazarus 2.2.4, FPC3.2.2
CPU-Target: X86-64; arm 32bit
Wohnort: Illertissen
Kontaktdaten:

Re: Behandlung vermutlich nicht-konformer EXIF Metadaten mit "fpExif"

Beitrag von h-elsner »

Vielen Dank! Wow, damit hätte ich gar nicht gerechnet, dass die XMP Daten nun auch wieder geschrieben werden können. Das ist eindeutig ein Fortschritt für mich. Ich hatte die Daten eingelesen und in einer JSON Datei in den UserComment geschrieben, um die Werte quasi zu 'retten'.

Das Projekt ist hier zu finden. Es soll in der Landwirtschaft eingesetzt werden, um Bilder mit verschiedenen Zusatzdaten zu Taggen, die später in anderen Anwendungen ausgewertet werden sollen.
https://github.com/h-elsner/EXIFupdate

YUN00003.jpg ist einfach eine zweite Datei für Fall 1 mit anderer Auflösung, quasi zum Gegenprüfen.

Ich werde mal ausgiebig mit Bildern verschiedener Yuneec Kameras, die XMP Daten verwenden, testen.

Gruß HE

wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: Behandlung vermutlich nicht-konformer EXIF Metadaten mit "fpExif"

Beitrag von wp_xyz »

h-elsner hat geschrieben:
So 17. Jan 2021, 19:53
Ich hatte die Daten eingelesen und in einer JSON Datei in den UserComment geschrieben, um die Werte quasi zu 'retten'.
Irgendwo habe ich zu EXIFTool gefunden, dass es die XMP-Daten gar nicht ausgibt, weil diese nicht mehr liefern als in EXIF ohnehin drinsteht. Kannst ja mal draufschauen und bei Gelegenheit zurückmelden, ob das so ist. Wenn ja, dann könnte ich mir die Arbeit mit XMP sparen... :)

[EDIT]
Das scheint aber nicht zu stimmen, denn in dem XMP-Datensatz finde ich Werte für CameraYaw, CameraPitch und CameraRoll, also wie die Drohne bei der Aufnahme ausgerichtet war. Bei den EXIF-Daten ist mir das nicht aufgefallen.

[Noch ein EDIT]
Ich habe gerade die XMP-Spezifikation gefunden, und da steht, dass hinter der XMP-Kennung "http://ns.adobe.com/xap/1.0'" ein Null-Byte steht. Das ist in deiner Datei nicht vorhanden. Hast du die XMP-Struktur selbst geschrieben, oder war das die Kamera?

Benutzeravatar
h-elsner
Lazarusforum e. V.
Beiträge: 259
Registriert: Di 24. Jul 2012, 15:42
OS, Lazarus, FPC: LINUX Mint21.1, Win10, Lazarus 2.2.4, FPC3.2.2
CPU-Target: X86-64; arm 32bit
Wohnort: Illertissen
Kontaktdaten:

Re: Behandlung vermutlich nicht-konformer EXIF Metadaten mit "fpExif"

Beitrag von h-elsner »

Die Kamera hat die XMP-daten geschrieben. Das Bild kam so von der Kamera. Allerdings hat der Kollege das Bild verkleinert. Ich habe habe auch Originale und kann da reinschauen.
Ich melde mich...

Übrigens hab ich mal fpExif r7965 weiter getestet mit LINUX Mint und Win10, sowie verschiedenen Kameras, darunter auch EXIF-Version 0221 statt sonst 0230. Sieht alles sehr gut aus, keine Probleme bei Lesen oder Schreiben entdeckt.

Gruß HE

Benutzeravatar
h-elsner
Lazarusforum e. V.
Beiträge: 259
Registriert: Di 24. Jul 2012, 15:42
OS, Lazarus, FPC: LINUX Mint21.1, Win10, Lazarus 2.2.4, FPC3.2.2
CPU-Target: X86-64; arm 32bit
Wohnort: Illertissen
Kontaktdaten:

Re: Behandlung vermutlich nicht-konformer EXIF Metadaten mit "fpExif"

Beitrag von h-elsner »

Die Null haben die wohl vergessen. Es ist so, dass bei CGO3+ (EU als auch FCC firmware) das NullByte fehlt. Bei den Nachfolge-Kameratypen (wue C23 oder E90) ist es dann aber richtig eingestellt.
YUN00025_CGO3Plus_HexView.txt
(10.07 KiB) 57-mal heruntergeladen
YUN00014_CGO3Plus_HexView.txt
(10.07 KiB) 55-mal heruntergeladen
YUN_0025_C23_HexView.txt
(30 KiB) 69-mal heruntergeladen
YUN_0012_E90X_HexView.txt
(30 KiB) 52-mal heruntergeladen
Gruß HE

Antworten