Teil 3: Abwärtskompatibel? Wenn Datenbreiten geändert werden.
In Teil 2 habe ich es schon angerissen. Die Struktur von Exif ist quasi eine Tiff-Struktur mit eigenen Tag-Werten. Es werden aber auch alte Werte aus der Tiff-Spezifikation 6.0 übernommen und weiter verwertet.
Begonnen wird die Struktur mit einer Kennung, die kennzeichnet, ob Zahlen nach der Intel(II=Little Endian) oder Motorola(MM-Big Endian) kodiert ist. Das nennt man ByteOrder. Gefolgt von einem 2-Byte Integer mit der Zahl des Lebens 42, geschrieben nach der ByteOrder Konvertion. Danach eine 4-Byte Integer als Sprungadresse, die meist 8 lautet. So fängt jedes Tiff-Bild und jede Exif-Struktur an. (Bei Raw steht statt 42 dann ein individueller anderer Wert). Nun kommt der IFD, das Image File Directory mit einem 2 Byte Integer, der die Anzahl der Tags anzeigt, die gleiche Anzahl von 12 Byte langen Directory IFD-Einträgen (IFDTag), gefolgt von einem 4 Byte Zeiger auf den nächsten IFD, der auch NULL betragen kann, dann kommt im Anschluss der Datenbereich. Daten sind auf 2 Byte-(WORD)Grenzen ausgerichtet. Ein IFDTag (Eintrag) besteht aus einem Tag, der 2-Byte ID, dem Typ, der sagt, wie der Wert zu interpretieren ist, der Längenangabe, wie oft der Typ wiederholt wird und dem kombinierten 4-Byte großem Wert/Zeiger-Bereich. Nach dem letzten IFDTag kommt ein Zeiger auf den nächsten IFD oder NULL und dann in der Regel der Datenbereich.
Früher hat man bei Tiff-Dateien auch gerne die Daten zuerst geschrieben und den IFD am Ende der Datei. Das ist aber gegen die Exif-Konvention. Ging aber schneller und man brauchte nicht so viel denken und einem Rutsch kodieren und nur die Sprungadresse nachtragen, die natürlich nicht 8 lautete. Nach Exif-Konvention muss man quasi einen 2 Pass-Encoder schreiben und sich alle Speicheradressen merken, in die dann die der Datenoffset nachträglich eingetragen wird. Dazu müssen erst mal alle Längen ermittelt werden.
Wie im Teil davor hatte ich die Typen ja schon angesprochen. UNKNOWN(Typ=0), BYTE(Typ=1), ASCIIZ(Typ=2) alle 1 Byte pro Einheit, SHORT(Typ=3) 2 Byte Integer(Ganzzahl), LONG(Typ=4) 4 Byte-Integer, RATIONAL(Typ=5) 8 Byte großer Bruch aus 2 LONG-Werten. Dann wiederholt sich das erst mal mit den ganzen Vorzeichen behafteten Werten etc…. Bei jedem Wert muss geprüft werden, ob er im Verzeichniseintrag Platz hat, oder in den Datenbereich geschrieben werden muss. Macht man einen Fehler, überschreiben sich die Daten gegenseitig.
Eigentlich sollte hier ganz was anderes stehen, aber das wurde schon früher eingeführt und wir haben es überlebt! Datengrößen die geändert werden können. Tatsache ist, dass diese Tags schon alle im LONG-Typ geschrieben werden.
Dafür ist mir heute ein anderer Fallstrick beim Codieren von Exif 3.0 aufgefallen. Textlänge ist nicht gleich Bytelänge bei UTF, wen wundert es?. Wird einer Struktur ein Text übergeben für den Typ ASCIIZ, so ist Textlänge gleich Bytelänge. Alles lässt sich wunderbar leicht übertragen. Quasi 1 zu 1., denn die Umkodiererei passiert eine Etage/Abstraktion höher.
Beim neuen Typ UTF-8 ist das nicht mehr der Fall. Nun übergibt man eine Unicode-Zeichenkette an die Low-Level-Routine und die codiert selber um und da ist eben nicht Text-Länge gleich Byte Länge. Zeichen mit dem Wert größer 127 Bit werden mit 2 Bytes kodiert. Das heißt, alle Längen-Berechnungsroutinen müssen geprüft werden und der Text über den Text-En-/Dekoder gejagt werden. Wenn man alle Stellen gefunden hat, sollte es sogar schneller funktionieren. Man spart sich 2 Codiervorgänge und Suchroutinen, die feststellen, ob ein Text noch UTF-8 kodiert ist oder schon auf Unicode umgerechnet oder halt Codepage 1252 auf Windows Rechnern in Deutschland. Hat man die Bibliothek selber geschrieben, kennt man die wichtigen Stellen. Nutzt man Fremdbibliotheken muss man, wenn man den Quelltext hat, suchen, wo die Fallen sind, oder warten, bis der Hersteller den Typ einbaut.
Interessant werden die Codestrukturen werden, die das nächste Kapitel betreffen. Denn zu JUMBF oder JSON LF kann ich noch nicht viel aussagen. Damit musste ich mich bisher nicht abgeben. Und dann heißt es: Lernen und selber Bibliotheken bauen oder welche finden, damit nicht jedes Rad neu erfunden werden muss. Erfahrungsgemäß können fertige Bibliotheken gerade leider das nicht, was man gerade braucht oder die Einarbeitung dauert länger, als wenn man es selber lernt und schreibt. Zumindest bei Datenstrukturen.
Teil 4: Neu: Bereiche in Exif 3.0. 2 Beschreibungssprachen?
In JPEGs gibt es jetzt einen neuen Bereich, der im APP11-JPEG-Marker abgelegt wird. Wir erinnern us: JPEG-Marker sind Datenblöcke, die benötigt werden um entweder bildrelevante Strukturen aufzunehmen oder Metadaten. Einige App-Marker-Nummern sind mehrfach belegt, weshalb idR noch eine Kennung angehängt ist. Beispiele sind dafür der APP1-Marker, der sowohl Exif, als auch XMP aufnehmen kann. Es ist sogar eine Reihenfolge dafür festgelegt, welcher der Marker zuerst geschrieben werden muss. Das gilt auch für andere Marker. Gut bekannt sind noch APP0 (JFIF-Kopf und JFXX-JPEG Vorschaubild), APP2 (ICC-Profil), APP12 (Adobe, Alte Olympus Metadaten, wird auch von anderen Herstellern verwendet z. B. für ICC-Profile), APP13(Adobe Photoshop 3.0 Marker, der auch IPTC-IIM Daten enthält, da Adobe das als Referenzhersteller implementiert hat). Die App-Marker-Struktur ist wesentlich einfacher zu handeln als die TIFF-Struktur, hat aber einen Haken: Die 64k Grenze. Nur wenige Definitionen können diese durchbrechen. XMP durch mehrere APP-Marker, ICC-Profile und nun auch der APP11-Marker.
Der APP11-Bereich kann mit weiteren Daten aus dem Exif-Standardbereich angefüttert werden. Aber darüber wird sich nicht weiter ausgelassen. Ist ein „Entlastungsbereich“ für den „Standard“-Exifbereich in APP1, der oft mit großen Vorschaubildern in den MakerNotes an die Grenze der 64k anstößt. Blockstruktur vermutlich, um die neueren Bildformate zu entsprechen, die oft nach ISO-BMFF (ISO-Base Media File Format) strukturiert sind.
Wo die entsprechenden Daten in RAW- bzw. Tiff-Bildern abgelegt werden, habe ich nicht gefunden. Vielleicht wurde es gut versteckt oder auch vergessen? Also doch wieder MakerNotes und XMP?
Aber zurück zum Thema. Hier kann eine Dokumentation auf Basis des „JPEG Universal Metadata Box Format“, kurz JUMBF (ISO/IEC 19566-5:2019) aufgebaut werden. Dazu ist der rudimentäre Aufbau in der Exif-Dokumentation beschrieben und ein paar Werte, die darin enthalten sein können. Es gibt sogenannte Beschreibungs- und Inhalts-Boxen, die mit XML oder gleichrangig mit JSON-LD beschrieben werden können (Warum denn beim Schreiben entscheiden? Der Reader muss beide Beschreibungssprachen eh können, heißt doppeltes Testen, doppelte Fehlerquellen). Exif hat eine eigene Kennung dafür bekommen. Man kann unter anderen dadurch Bildbereiche zusätzliche Informationen anhängen. Steht also teilweise in direkter Konkurrenz zu MWG (Metadata Working Group), deren Definitionen in der Archivversenkung verschwunden sind. Der Vorteil von MWG-Rahmen zu den neuen Exif-Areas: Relative Größen und Koordinaten. Zumindest bei einer Skalierung geht nichts verloren. Bei den neuen Daten müssen die Werte bei JEDER geometrischen Veränderung angepasst werden.
Nun kann Exif aber auch komplizierte Bereiche…. Es können in den Bildern, Rechtecke, Punkte, Linien, Polygone, Kreise Ellipsen, die auch noch im Winkel definiert werden können, angelegt werden, um dafür Informationen zu hinterlegen. Für die Anlegung soll aber bitte die Richtlinien CIPA DCG-001-2018 und CIPA DCG-002-2016 berücksichtigt werden. Trotzdem hat es was. Man kann mit den Linien, Kreisen, Ellipsen, Polygonen in einem Gruppenbild alle Köpfe oder die ganze Person schön sauber die Umrisse einfangen und gezielt mit den Umrissen exportieren, wenn es das Programm eingebaut hat. Oder das Auto oder was immer gerade das Motiv ist. Da dauert dann die Metadatenbearbeitung länger als die ganze Bearbeitung für das Bild. Aber gut für KI-Suchalgorithmen, Compositing und Informationsbeschaffung.
Was mich betrifft? Ich bau die APP-11 Geschichte erst in WPMeta ein, wenn ich ein paar Beispielbilder der großen Software-/Hardwarehersteller bekomme (z. B. mit AF-Feldbeschreibungen) und sonst nach Möglichkeit weitestgehend abwärtskompatibel Daten schreiben.
Erst kürzlich habe ich wieder von einem Smartphone-Markenhersteller Bilder mit Metadaten bekommen, die sich nicht an die Konventionen (MWG) halten. Dialekte und Unsauberkeiten können nerven, wenn man eine Software absturzsicher halten will. Finde den Fehler… aber das ist eine andere Geschichte.
Was bringt Exif 3.0? Viel Arbeit für die Softwareentwickler und neue Fehlerquellen in kommender und bestehender Software. Wird das Chaos besser? Nein, nur anders und vielfältiger. Für den Endverbraucher: Mehr Möglichkeiten, seine Zeit tot zu schlagen. Für Datendetektive: Mehr Möglichkeiten Fälschungen aufzudecken. Für Spione: Mehr Möglichkeiten Daten sichtbar zu verstecken….
Kommentar RW: Das größte Problem wird sein, dass liebgewonnene Software, die jahrzehntelang anstandslos ihren Job gemacht hat, auf einmal die Arbeit einstellt.
Phil Harvey, Autor des beliebten EXIFTOOL ist noch deutlicher:
„I’m just getting around to looking at this. As usual, the spec is poorly written, incomplete, and full of errors. Plus, it isn’t very backward compatible. I’ll see what I can do with this mess.“
https://exiftool.org/forum/index.php?topic=14887.msg80246#msg80246
Hoffen wir mal, dass OMDS den nötigen Aufwand für den Umstieg nicht spendieren mag. In diesem Fall wäre Geiz ausnahmsweise mal geil.
“Beim neuen Typ UTF-8 ist das nicht mehr der Fall. Nun übergibt man eine Unicode-Zeichenkette an die Low-Level-Routine und die codiert selber um und da ist eben nicht Text-Länge gleich Byte Länge. Zeichen mit dem Wert größer 127 Bit werden mit 2 Bytes kodiert.”
Das ist so nicht ganz richtig. Zuerst mal brauchen wir eine Begriffsklärung. Unicode ist gewissermaßen der Nachfolger des alten ASCII, also eine riesengroße (abstrakte) Tabelle, in der (theoretisch) alle Schriftzeichen, mathematischen Zeichen, Symbole, … der Welt enthalten sind und jeweils eine Positionsnummer, den sog. “Codepoint”, zugeordnet bekommen. Der Unicode enthält aktuell so um die 145.000 Zeichen (etwas mehr als die 128 des ASCII). Das Ganze ist komplizierter, als man vielleicht meinen würde, weil man z.B. berücksichtigen muss, dass viele Sprachen von links nach rechts geschrieben werden, aber andere von rechts nach links, und es vorkommen kann, dass man innerhalb eines englischen Textes (von links nach rechts) einen hebräischen Text (von rechts nach links) zitiert, der wiederum einen russischen Text (von links nach rechts) zitiert (nur mal so als Beispiel). Dazu kommen diakritische Zeichen – in Deutsch etwa die Pünktchen auf ä, ö und ü, was erst mal klingt wie kein so großes Problem, bis man bei Altgriechisch oder Vietnamesisch landet, wo die Dinger sich stapeln können. Viele – aber nicht alle – chinesischen Zeichen, die benutzt werden, um Japanisch zu schreiben, sehen so aus wie ihre chinesischen Pendants: darf oder sollte man die dann unter derselben Codepoint-Nummer zusammenwerfen? Und so weiter … die technischen Details sind nicht appetitlich, von den politischen ganz zu schweigen.
Was im Unicode mit Absicht nicht festgelegt ist, ist, wie diese Codepoints in Computern dargestellt werden. Eine Weile lang hat man etwas blauäugig gedacht, man müsste einfach nur zwei Oktette pro Zeichen nehmen statt einem (eine als “UCS-2” bekannte Codierung). Abgesehen davon, dass 65536 Codepoints hinten und vorne nicht reichen (Stichwort: Chinesisch und Japanisch), wird dadurch der benötigte Speicherplatz für typische englische Texte (die von den beiden Oktetten nur eins tatsächlich benutzen) verdoppelt und die codierten Texte strotzen von Nullbytes, was es schwerer macht, sie in Programmiersprachen wie C zu verarbeiten, wo ein Nullbyte das Ende der Zeichenkette angibt. Außerdem muss man sich überlegen, ob man das höherwertige oder das niederwertige Oktett zuerst hinschreiben will (“Endianness”). (Heute sind die allermeisten Computer “little-endian”, d.h., das niederwertige Oktett kommt zuerst, aber wir sind noch nicht so weit, dass wir das Problem ignorieren könnten.)
An dieser Stelle kommt UTF-8 ins Spiel: UTF-8 (entworfen von den Unix-Miterfindern Ken Thompson und Rob Pike) ist eine Methode dafür, Unicode-Codepoints hinzuschreiben, die die folgenden netten Eigenschaften hat: (1) Die Codepoints für “normale” (7-Bit-)ASCII-Zeichen passen in ein Oktett, es wird also im sehr wichtigen Anwendungsfall von Englisch und anderen mittel- und westeuropäischen Sprachen wenig oder kein Speicherplatz verschwendet; (2) Codepoints ab 128 werden durch 2–6 Oktette dargestellt – je größer die Codepoint-Nummer, desto mehr Oktette sind nötig. Die Darstellung solcher Codepoints enthält keine Oktette, die mit 7-Bit-ASCII-Zeichen verwechselt werden könnten, und man sieht am ersten Oktett, wie viele noch kommen, d.h., wenn man aus irgendwelchen Gründen in die Mitte einer UTF-8-Zeichenkette hineinspringt, kann man Oktette verwerfen, bis man an den Anfang des nächsten Zeichens kommt. (3) Nullbytes können weiter als Zeichenketten-Endemarkierung benutzt werden. (4) UTF-8-Zeichenketten ergeben beim lexikografischen Sortieren dasselbe Ergebnis wie wenn man die Unicode-Codepoint direkt sortieren würde. (5) Man muss sich nicht um “Endianness” kümmern. Das Euro-Zeichen (€) zum Beispiel hat im Unicode die Codepointnummer 8364, vulgo U+20AC oder binär dargestellt 00100000 10101100. Per UTF-8 ergeben sich daraus die drei Oktette 11100010 10000010 10101100; wenn man sich einen Text mit diesen drei Oktetten mit einem Programm anschaut, das nur die Windows-Codepage 1252 unterstützt, dann sieht das aus wie “€”. Solange ein Text vor allem Zeichen enthält, die auch im alten ASCII zu finden sind (und in UTF-8 nur ein Oktett brauchen) ist das aber kein großes Problem.
Als UTF-8 erfunden wurde, war Microsoft leider schon mit UCS-2 vorgeprescht, das sich später als nicht tragfähig erwies. Mit UCS-2 kann man die ersten 65.536 Codepoints, die sogenannte “Basic Multilingual Plane”, darstellen, aber z.B. Emojis (die zum größten Teil Codepoint-Nummern oberhalb von 65.536 haben) bleiben außen vor. Statt dessen gibt es UTF-16, das mit einigen Verrenkungen versucht, größere Codepoint-Nummern als Folgen von 16-Bit-Wörtern hinzuschreiben. Dieser Ansatz ist mit einigen Macken versehen; “Endianness” zum Beispiel bleibt ein Problem.
Also zusammenfassend: Unicode ist (wie ASCII) eine Methode, Buchstaben, Ziffern usw. Nummern zuzuordnen, damit man sie in einem Computer verarbeiten kann. UTF-8 (fast überall) und UCS-2/UTF-16 (bei Windows, Java usw.) sind Methoden, wie man diese Nummern für einen Computer aufbereitet (ASCII-Nummern werden einfach direkt benutzt). UTF-8 ist eine oktett-basierte Darstellung, die eine Zeichen-Nummer (Codepoint) durch 1-6 Oktette ausdrückt. Demzufolge ergibt es keinen Sinn, von einer “Umrechnung von UTF-8 nach Unicode” zu reden, denn UTF-8-Zeichenketten *sind* schon Unicode. UTF-8-codierte Zeichenketten können überall da benutzt werden, wo man “normale” nullterminierte Zeichenketten benutzt, wenn man sich nicht daran stört, dass die Länge des Textes in Oktetten nicht mehr notwendigerweise der Länge des Textes in Zeichen entspricht. Man kann gewisse (kleine, aber wichtige) Teilmengen von Unicode auch mit der Windows-Codepage 1252 darstellen, aber im 21. Jahrhundert ist das veraltet; wenn man nicht die Möglichkeit hat, auf UTF-8 umzusteigen, muss man evtl. UTF-16 benutzen, was unbequemer ist und (zumindest hierzulande) Speicherplatz verschwendet.
Hi,
ich kann hier nur von Windows Systemen sprechen. Die verwenden intern UCS2 in westlichen Systemen, quasi das volkstümliche Unicode in Intel Notation. Jeder Buchstabe wird in Char, einem 2 -Byte Wert codiert. Alles was von außen kommt in Form von Byte Arrays muss dahin codiert werden. Es gibt inzwischen auch UCS4, was hierzulande kaum Bedeutung hat. Sämtliche API Funktionen können 8Bit Codepage ASCII und UCS2, sind die Funktionen mit W am Ende. Neben UTF-8 gibt es noch UTF-16 und sogar UTF-32, wenn ich mich nicht irre. Zum Glück gibt es fertige Funktionen dafür, auch dafür, den Speicherplatz zu ermitteln. Sonst wird man vor lauter Vorschriften wahnsinnig. Einzig eine Funktion, die fest stellt, ob falsch codiert wurde, musste ich selber schreiben. Die prüft Byte für Byte und wenn ein Fehler auftritt, ist es kein UTF 8 und muss nicht umkodiert werden. War bisher notwendig bis Exif 2.32. Wegen der Abwärtskompatibilität sogar noch länger. Umcodieren heißt hier: Zurück zum Bytearray und mit der richtigen Codepage wieder in String überführen. Wenn man es falsch macht, hat man nur noch Fragezeichen…
Das Problem mit UCS-2 ist, wie erwähnt, dass man auf die BMP beschränkt ist (d.h., zum Beispiel keine Emojis bis auf simple Smilies und Frownies; ob das ein Problem ist, muss man halt für sich entscheiden – andere Zeichen außerhalb der BMP, etwa einige afrikanische und asiatische Alphabete, historische Schriftzeichen, Mah-Jongg-Steine und selten gebrauchte chinesische und japanische Zeichen kann man vielleicht eher verschmerzen). UCS-2 ist auch die offizielle Zeichencodierung für SMS, aber weil Emoji da ein wichtiger Use-Case sind, implementieren praktisch alle SMS-Provider heimlich UTF-16. UCS-2 gilt seit Unicode 10.0 offiziell als veraltet.
UTF-16 ist der Versuch, UCS-2 zu erweitern, so dass Codepoints außerhalb der BMP zugänglich werden. Das ist das, was die Windows-APIs heutzutage benutzen. Der Ansatz ist dabei ähnlich wie bei UTF-8; Zeichen mit Codepoints > 65.535 werden mit zwei 16-Bit-Wörtern dargestellt, wobei deren Werte so gewählt werden, dass sie nicht mit gültigen Unicode-Codepoints kollidieren (dafür wurde in der BMP der Bereich 0xD800-0xDFFF freigelassen, die “UTF-16 surrogate range”). Ein UTF-16-Datenstrom besteht also aus einzelnen 16-Bit-Wörtern, die Codepoints in der BMP außerhalb der “surrogate range” enthalten, und Paaren von 16-Bit-Wörtern aus der “surrogate range”, die Codepoints außerhalb der BMP kodieren. Mit UTF-16 kommt man bis zum Codepoint U+10FFFF, und da ist dann auch das Ende der Fahnenstange erreicht, weil man UTF-16 nicht mehr ändern kann. Das entspricht 1.112.064 Codepoints, und zum Glück sind wir von dieser Grenze noch ein gutes Stück entfernt.
UCS-4 ist die Idee, dass man einfach jeden Unicode-Codepoint in einer 32-Bit-Ganzzahl darstellt. Das ist sehr bequem, hat aber den Nachteil, dass typische englische Texte (und andere, die sonst auch mit etwas wie ISO-Latin-9 ausgekommen wären) auf das Vierfache aufgebläht werden. Das ist auch der Hauptgrund, warum niemand UCS-4 benutzen will – RAM, Plattenplatz und Netzbandbreite sind heute zwar billiger als früher, aber trotzdem möchte man sie nicht mutwillig auf diese Weise verschwenden. UTF-32 hat nichts mit UTF-8 und UTF-16 zu tun, sondern ist im Wesentlichen ein anderer Name für UCS-4.
Das Ganze ist unglaublich kompliziert: Wenn man eine Codierung wie UTF-8 oder UTF-16 verwendet, dann ist die Länge einer Unicode-Zeichenkette gemessen in Codepoints nicht notwendigerweise gleich der Länge einer Unicode-Zeichenkette gemessen in Bytes. Aber selbst zwischen Codepoints und (sichtbaren) “Zeichen auf dem Bildschirm” besteht keine 1:1-Korrespondenz – zum Beispiel werden Nationalflaggen wie (mal sehen, ob Reinhards Software dieses Schwarz-Rot-Gold durchlässt und wenn ja, wie) im Unicode als Kombination von zwei Codepoints dargestellt, auch wenn sie auf dem Bildschirm ein einziges Zeichen sind. Bei manchen Zeichen wie “ä” kann man sich aussuchen, ob man sie als vorgekochtes Zeichen benutzen will (U+00E4) oder als Kombination aus “a” (U+0061) und “¨” (U+00A8) – was natürlich Probleme aufwirft, wenn man sortieren oder suchen möchte. Das heißt, es müssen “Normalformen” definiert werden, um solche Mehrdeutigkeiten zu umgehen. Und dann gibt es natürlich auch noch das Security-Problem, dass in einem URL wie https://www.microsoft.com zum Beispiel ein “o” in “microsoft” ein kyrillisches Zeichen sein könnte, das optisch nicht von einem lateinischen “o” zu unterscheiden ist, aber dafür sorgt, dass man auf eine völlig andere Web-Seite geleitet wird (moderne Web-Browser warnen inzwischen bei sowas). Zu deutsch: Es gibt zahllose Möglichkeiten, sich in den Fuß zu schießen, und darum sollte man, so weit man irgendwie kann, auf Betriebssystem- und Bibliotheksfunktionen zurückgreifen, denn da ist die Chance größer, dass die schlimmsten Klopfer schon gefunden und behoben wurden.
Das in Windows intern nicht mehr UCS2 verwendet wird, ist an mir vorbei gegangen. Da der Datentyp String aus dem Typ Char mit 2 Bytes besteht. Aber Ihre Ausführung erklärt, warum es möglich ist, einen UTF-8 Text in ein Control zu importieren, dessen Zeichen per Tastatur nicht mehr eingebbar sind. Habe nachgeschaut, ist ein 4 Byte langer Code. Ich hatte mich schon gefragt, wie die das gemacht hatten.
Bei einem anderen Projekt, dass ich privat für mich verfolge, archiviere ich EMails, die im archivierten, komprimierten Zustand lesbar sein sollen. Da ist eine Mail rein gekommen, das hatte einen Anhang eine Mail mit einem Dateinamen, der mit einem exotischen Emoji begann. Bis auf Thunderbird sind alle mir bekannten EMail-Programme ausgestiegen. Das wird wohl auch so ein UTF-8 Zeichen mit 4-Byte Länge uncodiert sein. Es macht auf jedem Fall viel Probleme.
Und keine Angst. Für das De-/Kodieren verwende ich eine Microsoft-Bibliothek. Nur will ich einen Text nicht testen, indem ich auf einen Fehler warte. Fehlerhandling kostet CPU-Zeit, die sich schnell summiert, da sehr aufwändig. Da ist es schneller, zu iterieren und die möglichen Bytefolgen selber abzuchecken. Dazu muss ich nicht mal wissen, was das für ein Zeichen wird. Passt oder wird passend gemacht.
Die neue Implementation dreht den Spieß übrigens um. Jetzt muss ich zwar beim Lesen immer noch prüfen, ob es ein UTF-8 Text ist (nach MWG V2 kodiert). Beim Schreiben muss ich jetzt aber prüfen, ob es 7-Bit ASCII ist. Ist das es ASCII-7-Text, dann Typ ASCIIZ, ansonsten Typ UTF-8. Der neue Tiff-Datentyp hat tatsächlich beim Lesen auch Probleme bereitet. Wenn man MakerNotes dekodiert, die auch Fehler enthalten können, wegen verschobenen, nicht angepassten Offsets, muss man aufpassen, was man liest und interpretiert. Was nicht bekannt ist, wird geskipt. Prompt wurde der Tag zwar gelesen aber mit 0-Länge aussortiert, weil offensichtlich fehlerhaft. In der internen Testversion bereits korrigiert.
Bei einem befreundeten EBV-Entwickler wird es auch noch länger dauern. Der hat sein Programm gerade zerlegt, um komplett auf höhere DPIs umzustellen. Der liest und schreibt die neuen Tags zwar, aber intern wird Exif nicht mehr angezeigt. Komplett. Kein Exif-Vorschaubild, nichts. Der entnimmt die Daten, patcht 2 Werte für Breite und Größe und schreibt ansonsten das ganze Datenpaket uninterpretiert wieder zurück. Normalerweise kann man die Werte intern oder per Skript lesen und ändern.