Source Codes











David Vajda
Eugestraße 61
D-72072, Tübingen
+4917647240501
e-mail: david.vajda@supra-net.net
http://46.223.66.127
http://www.dvajda.de


Ein Programm zu Smiley's: http://www.talkortell.de/bmpproject/smileyready.html

Ok, es funktioniert.
Variante 3


Jetzt kommt der Witz bei der Geschichte: Was ist bei dem Multiplizieren. Na ein Stern hat 5 Ecken, also machen wir den anderen Ausdruck, wenn er entsprechend auf der anderen oder richtigen Seite steht 5 Mal. Aber was ist wenn wir Mal (Quadrat+Stern) machen? Dann ist die Sache ganz einfach: Ein Quadrat hat 4 Ecken, ein Stern 5, also, da beide addiert werden, *9.
Das würde auch unserem graphischen Muster entsprechen. Denn wir müssen nicht so denken, wir bringen um das Muster herum überall außen neue Figuren oder Elemente an (also zusammengesetzte Elemente), sondern wir bringen rekursiv quasi auf jede Ecke, die in dem Muster vorhanden ist, ein Element an. Das müsste man dann natürlich entsprechend graphisch machen, was in HTML nicht so einfach möglich ist. Das könnte man besser in Qt4 machen, wo man auf eine Ecke, ein altes Bild anbringt. Wenn man ganz graphisch denkt. Damit die Sache mit 9 Ecken, also zum Beispiel einem Viereck und einem Stern auch geht, verwende ich zum Abzählen der Ecken keinen Stack, der die Strings enthält und durchsucht wird, wie viele Ecken vorhanden sind, sondern einen parallelen Stack. Der parallele Stack enthält die Anzahl der bereits existierenden Ecken.


Variante 2


So, jetzt ist es endgültig fertig.


Ok, es funktioniert. So ein Mist mich genervt. Am Anfang wird eine Variable definiert. Und initialisiert. Erst war sie nicht definiert, da ging nichts, dann war sie nicht initialisiert.


Jetzt mache ich die Sache noch einfacher. Ich bin ja so gut wie fertig. Aber so verrückt bin ich ja jetzt auch nicht. Also abstrahieren wir weiter. Ich bin schon so gut, wie fertig, mein ADD ist fertig und ersetzt prima, Kreise und Quadrate und Sterne und bindet sie nebeneinander an. Hintereinander. Das funktioniert schon, das sehe ich. Aber so verrückt bin ich auch nicht. Wir hatten zunächst als Definition von Multiplizieren: Einen Stern multipliziert man, indem man an jede Ecke etwas dran hängt. Ein Quadrat ebenso. Kreis ist neutrales Element. Dann ging es aber darum: Vereinfachen. Das würde jeder einsehen. Wenn man an ein Quadrat an jede Ecke etwas dran hängt, dann könnte man sich das auch einfacher vorstellen: An jeder der 4 Kanten oder 4 Kanten hängt man etwas. Umgekehrt: Beim Stern, an jede Ecke. Man kann das verstehen, das aus dem einen, das andere wird. Umgekehrt kann man nun aber sagen: Na wenn ich oben, unten, rechts und links etwas dran hänge, kann man die Sache ja noch einfacher machen. Oben und unten und links und rechts. Das bedeutet, man muss skalieren. Das ist nämlich so eine Sache. Wenn ich einen Eintrag in der Tabelle habe, der aus 3 Spalten besteht und hänge den an einen dran, der aus 1er Spalte besteht, dann muss ich die 3 Spalten so skalieren, dass sie jeweils gedrittelt werden. Das wird unangenehm. Umgekehrt, wenn ich oben und unten und links und rechts, warum nicht gleich folgendes: Warum nicht einfach nur Links und einfach nur Rechts, dann nicht noch oben und unten. Beim + hängen wir nach links etwas dran, beim * links und rechts.


So, jetzt zu unserem "Stern-Viereck-Kreis" Modell, addieren und subtrahieren. Die erste Idee ist: Wir haben ja jetzt einen Compiler. Und der Compiler arbeitet so: Zunächst wird mit dem Parser der arithmetische Ausdruck ausgewertet. Im selben Atemzug aber, arbeitet der Compiler (Compiler, wenn man so will). Was tut der denn bisher. Bei a+b. Kommen die Operationen: POP A; POP B; PUSH A+B; Wir haben es mit zwei POP's zu tun und der neue Wert wird auf den Stack gepusht. Also: POP, POP, PUSH. Und der von PUSH gepushte Wert, landet da, wo vorher der Wert von dem zweiten POP entnommen lag. Dasselbe Prinzip können wir jetzt auch machen. Wir arbeiten ja in HTML mit einer Tabele in HTML. Und jetzt der Clou: Diese Tabelle enthält ja keine Bilder. Sondern nur Text. Denn die Bilder werden nachher durch HTML eingebunden. Aber der HTML-Quelltext der besteht ja aus nur ASCII-Zeichen. Das heißt wir haben immer noch einen Stack. Wir arbeiten immer noch mit einer Stackarchitektur. Dabei landen auf dem Stack, keine Zahlen und auch keine Bilder, sondern Strings, die den HTML-Quellcode enthalten. Also ist der Stack wieder ein Array, aber dieser enthält als Elemente Strings. Also Zeichenketten. Am Ende große Zeichenketten. Wir machen zwei Mal POP mit einer alten Zeichenkette und ein Mal PUSH mit der neu entstandenen Zeichenkette.
Das ist doch eigentlich interessant. Wirklich interessant wird es aber, wenn man die Operationen '*' und '+' betrachtet. Diese Operationen sind dann natürlich keine arithmetischen Operationen mehr. Sondern Operationen, die an dem String arbeiten, der den HTML-Code enthält. Wir haben also zwei Mal POP von einem Array, das eine Table enthält und dann wenden wir eine arithmetische Operation an, die die beiden HTML-Codes verknüpft und PUSH't dann dieses Ergebnis erneut auf dem Stack. Bei '+' ist das ganz einfach vorstellbar: Wir hängen an ein Bild einfach ein neues Bild, hinten an. Das heißt wir erweitern den String der in einer Zeile von der Tabelle steht.
Und jetzt wird die Sache einfach, wir machen sie jetzt nicht zu kompliziert, sondern so einfach wie möglich, das ganze ist nur eine Demonstration. Wir sehen, eine Addition bedeutet ein strcat in C. Das heißt an denen einen String, wird ein anderer String angehängt. Die Definition von '*' ist zwar bei den Sternen, Kreisen und Vierecken einführbar, wie in der Arithmetik, aber: Es ist jetzt nicht unbedingt vorgeschrieben, was das automatisch heißt. Deswegen bedienen wir uns eines Tricks. Man könnte das auch galanter machen, aber zunächst, das. Wir wissen, dass es ganz einfach ist, einen String hinten an zu hängen. Ebenso einfach, ist es einen String davor zu hängen. Oder darüber oder darunter. Also verstehen wir unter '*' einfach: Wir hängen, links, rechts, oben und unten das eine Konstrukt an das andere.
Jetzt mache ich die Sache noch einfacher. Ich bin ja so gut wie fertig. Aber so verrückt bin ich ja jetzt auch nicht. Also abstrahieren wir weiter. Ich bin schon so gut, wie fertig, mein ADD ist fertig und ersetzt prima, Kreise und Quadrate und Sterne und bindet sie nebeneinander an. Hintereinander. Das funktioniert schon, das sehe ich. Aber so verrückt bin ich auch nicht. Wir hatten zunächst als Definition von Multiplizieren: Einen Stern multipliziert man, indem man an jede Ecke etwas dran hängt. Ein Quadrat ebenso. Kreis ist neutrales Element. Dann ging es aber darum: Vereinfachen. Das würde jeder einsehen. Wenn man an ein Quadrat an jede Ecke etwas dran hängt, dann könnte man sich das auch einfacher vorstellen: An jeder der 4 Kanten oder 4 Kanten hängt man etwas. Umgekehrt: Beim Stern, an jede Ecke. Man kann das verstehen, das aus dem einen, das andere wird. Umgekehrt kann man nun aber sagen: Na wenn ich oben, unten, rechts und links etwas dran hänge, kann man die Sache ja noch einfacher machen. Oben und unten und links und rechts. Das bedeutet, man muss skalieren. Das ist nämlich so eine Sache. Wenn ich einen Eintrag in der Tabelle habe, der aus 3 Spalten besteht und hänge den an einen dran, der aus 1er Spalte besteht, dann muss ich die 3 Spalten so skalieren, dass sie jeweils gedrittelt werden. Das wird unangenehm. Umgekehrt, wenn ich oben und unten und links und rechts, warum nicht gleich folgendes: Warum nicht einfach nur Links und einfach nur Rechts, dann nicht noch oben und unten. Beim + hängen wir nach links etwas dran, beim * links und rechts.


Das mit den Sternen, Kreisen und Quadraten, mache ich jetzt gleich. Ich schreibe einen Parser in JavaScript, der addiert, multipliziert Sterne und Kreise und Quadrate. Dabei ist darauf zu achten: Beim Multiplizieren werden an die Ecken von Quadraten und Sternen die anderen Figuren angebracht. Der Witz ist, es gibt jetzt ein neutrales Element. Wie könnte es anders sein: Der Kreis ist ein neutrales Element, wie die '0'. An ihn kann man nichts anbringen, an seine Ecken, weil er keine besitzt. Jetzt ist noch die Frage nach Kommutativgesetz. Da kann man zwei Wege gehen, das eine besagt, es gibt keines, das andere besagt, es gibt eines. Hier kann man aber so denken: Wenn erst Quadrat dann Kreis und beides wird addiert, dann steht, eben erst das Quadrat und dann der Kreis, oder man macht es kommutativ so, dass es immer das eine Element automatisch auf der einen Seite liegt. Umgekehrt kann man auch so kommutativ denken: Man vergleicht zwei Bilder und dabei ist es dann uninteressant, wo Kreis oder Quadrat liegt, das heißt, selbst, wenn diese vertauscht wären, würde es als Gleiches gelten. Die Sache programmiere ich in JavaScript. Und ich werde eine HTML-Tabelle benutzen, die von dem JavaScript-Parser generiert wird. Dabei werden bereits gemalte Bilder entsprechend angebracht.
Jetzt machen wir die Sache so: Sie vertritt drei Geheimnisse:
I. Die erste Sache ist, was ist mit einem zusammengesetzten Konstrukt. Wo sind da die Ecken? Ein Stern mit 5 Ecken, hat 5 Ecken und man hängt eines in die obere linke, in die obere Rechte, eines oben drauf, eines in die untere rechte usw. Aber was ist bei einem Zusammengesetzten Konstrukt? Nun, wir definieren die Multiplikation, dass in diesem Fall an alle außen besetzten Felder eines angehängt wird. Dann haben wir trotzdem multipliziert. Weil man denke: Das Gesamtkonstrukt, wenn es vier außen besetzte Felder hat, hat dann nach außen vier angehängte neue Konstrukte. Das entspricht somit in keinster Weise, der Addition, wo einfach Elemente recht seitig angehängt werden. Jetzt ist die Frage, wo bringt man die an. Na da kann man zum Beispiel so denken: Wenn ein Bild in einem Konstrukt auf der linken Seite, aber nicht unten angebracht wird, wird es auf derselben Zeilenebene links angebracht. Also kann man alle Bilder die angehängt werden, genau links oder rechts oder oben oder unten anbringen. Oder man macht es noch besser: Wenn, ein Konstrukt in der linken unteren Ecke ein Bild oder Konstrukt angehängt bekommt, dann wird es, aber nur bei der Ecke, in der linken unteren Ecke angehängt.
II. Man kann in HTML Tabellen in Tabellen einbauen. Das heißt, jedes Konstrukt wird in einer Tabelle untergebracht.
III. Jetzt die Frage zu der Skalierung. Zunächst: Müssen alle Sterne, Kreise und Quadrate, als einzelnes Bild ein gleiches Format haben? Nein HTML bietet die Möglichkeit die Breite und Höhe an zu geben. Wenn man ein Bild zeichnet und das so soll groß sein, wie das andere, dann gibt man eben beides Mal width="200" ein. Umgekehrt ist es so: Baut man eine Tabelle und zeichnet ein Bild mit der Höhe 400 ein, dann ist die Tabellenhöhe von der Zeile 400. Wenn man daneben parallel eine Tabelle zeichnet, mit der jeweiligen Zeilenhöhe von 200, ist das ganze wieder 400.


Ich habe eine Idee für den Compilerbau. Also, ich habe doch einen Funktionsplotter geschrieben, des weiteren mehrere Parser, die arithmetische Ausdrücke berechnen. Dann habe ich eine Art Pascal-Compiler geschrieben. Etwas eher kleines. Und ich habe einen Parser geschrieben, der Bäume ausgibt. Ich bin sogar so weit gegangen, dass ich einen eigenen Taschenrechner baue. Die Sache ist in so fern nicht gefährlich, dass es nicht funktioniert: Denn, ich habe bereits ein LCD-Display an einen Mikrocontroller angeschlossen. Ich habe auf Vorrat gekauft. Umgekehrt, benutze ich AVR-Mikrocontroller. Und diese lassen sich in C programmieren, nicht nur in Assembler. Das heißt, es lassen sich auch problemlos Routinen für Float und Fließkomma verwenden. Umgekehrt ist es so: Ein solches Display lässt sich einfach programmieren. Nun muss man blos, die C-Routinen für den Parser auf den Controller und das Display anwenden und schon hat man einen Taschenrechner mit ganzen Ausdrücken (Termen). Die Sache ist nicht viel schwieriger bei graphischen Displays. Graphische Displays sind zwar teuer, aber sie sind relativ einfach an zu steuern. Man braucht bloß den Buffer nach oben zählen und Bildpunkte setzen oder löschen. Der Befehlsvorrat ist ähnlich denen von Textdisplays.
Das lasse ich im Moment, ich habe schon damit angefangen, mein Textdisplay entsprechend dem C-Compiler an zu passen, mitsamt Controller. Da ich einen Funktionsplotter geschrieben habe, von der Darstellung ist der Plotter relativ einfach. Der Plotter zeichnet einfach nur eine Linie von dem einen Punkt zu anderen. Und die Punkte werden von Fließkomma nach Ganzzahl umgerechnet.
Als nächstes stünde, aber der Taschenrechner mit Term-Eingabe an. Ich habe wie gesagt, mit Assembler, bereits einen Text erzeugt, es wäre aber ratsam C zu verwenden, wegen dem Parser. Jetzt ist es leider so: Ich hatte Schwierigkeiten das C auf dem AVR-Controller zum laufen zu kriegen, also mittels Compiler. Das geschah unter Linux und nicht mit AVR-Studio. Ich weiß jetzt nicht, was mir näher liegt, knallhart sagen, ich verwende nur Linux und mache es solange bis es läuft, oder zum Abwechslung einen alten Rechner auftreiben und mit Windows 2000 AVR-Studio zu verwenden. Die Sache würde dann garantiert laufen. Da ist alles perfekt eingestellt.
Umgekehrt ist das gerade nicht mein Thema. Denn ich bin jetzt mit den BMP's weit gekommen und als nächstes probiere ich mich an den JPEG's. Damit habe ich ja schon angefangen. Die Cosinus-Transformation, die eigentliche Herausforderung, wie man meinen könnte, ist ja bereits implementiert und funktioniert. Das heißt, ich beschäftige mich gerade nicht mit dem AVR-Mikrocontroller, mitsamt Display und C-Compiler.
Jetzt aber ein anderes spannendes Experiment: Kann man Sterne und Kreise addieren, oder Quadrate? Nun ja, man kann eine Menge erstellen {Stern, Kreis, Quadrat} oder {5-Stern, 6-Stern, ..., Kreis, Oval, Quadrat, Viereck}. Kann man da nicht addieren und multiplizieren. Na ja, ähnlich wie Boole'sche Operatoren AND, OR, NOT Operationen sind die auf WAHR und FALSCH angewendet werden, sind es eben '+' und '*'. Niemand verbietet uns die Operationen '+' und '*' bei den Operationen auf {Stern, Kreis, Quadrat} nicht auch zu verwenden. Als Operationen, die in diesem Falle zwar Addition und Multiplikation genannt werden können, aber nicht müssen. Wie wäre es dann, wenn man unter der Addition von "Stern" und "Quadrat", die linksseitige Aneinanderreihung versteht. Multiplikation eines Sternes mit Kreisen würden bedeuten, wie hängen an jede Ecke vom Stern einen Kreis. Die Kreise und Quadrate und Sterne lassen sich graphisch darstellen. Ebenso ihren Zusammenbau. Sogar die Relativität zwischen beiden funktioniert. Gleiches Bild, gleiches Element. Oder es gilt zwischen den Zusammengebauten das Kommutativgesetz. Nun ließe sich dies einfach über einen Parser gestalten, der Parser setzt für jedes Element das er finden, das entsprechende ein und baut sie entsprechend zusammen. Umgekehrt kann man sich ja jetzt das Pattern-Matching zu Hilfe nehmen. Auch für Bilder. Pattern Matching bedeutet nicht, dass wir zum Beispiel mit dem KMP-Algorithmus, der sehr fein definiert ist, bestimmte Muster wie "ACD" suchen, sondern ein Suchmuster vorgeben *('e')... Wenn man sich nun vorstellt, das Pattern-Matching auf Bilder an zu wenden, könnte man sich folgendes vorstellen. Man lässt bereits das Pattern-Matching oder viel mehr eine Maschine, die Ausdrücke für das Pattern-Matching erstellt über ein Bild laufen, bei BMP ist das ganz einfach, weil die Bildpunkte direkt oder über eine Tabelle als Punkte und Werte angeben sind. Die Ausdrücke landen in einer Tabelle, die zum Beispiel über SQL gesteuert wird, SQL = Datenbank. Ein Pattern-Matching-Automat benutzt nun die Einträge, also die Ausdrücke des Pattern-Matchings für ein zweites Bild und vergleicht somit beide Bilder. Auf Gemeinsamkeiten, die dem Auge entgehen. Und die trotzdem nicht durch Zufall entstanden sind.


Diese Artikel habe ich ihnen bisher vorenthalten:


Es gibt eine Alternative zu MP3. Man speichert die Musik generell als Regulären Ausdruck. Dabei kann man zum Beispiel an Multiplizieren und Addieren denken. Da kann man den Mischer denken, additiver Mischer und multiplikativer Mischer. Man kann aber auch anders denken: Addieren bedeutet zwei Töne werden nebeneinander gespielt. Multiplizieren bedeutet, zwei Töne werden vermischt. Dann ist eben die gesamte Multiplikation eine Mischung.
Jetzt macht man die Sache aber noch besser. Schaut man sich BMP's an. Dann gibt es zwei Varianten. Die eine enthält für jeden Farbton bei jedem Pixel den Farbton selber, 24 Bit, 32 Bit, bietet an den Farbton direkt ein zu schreiben. Umgekehrt, kann man auch eine Tabelle denken. Schreiben wir den Farbton direkt, kann man an bereits existierende Töne denken. Zum Beispiel einen Klavierton, der einfach im Standardrepertoire enthalten ist. Nun gibt es eine bestimmte Menge an Tönen auf dem Keyboard. Eine bestimmte Menge an Ganztonschritten und Halbtonschritten. Auf eine Gitarre gilt letzten Endes dasselbe. Das heißt, hier könnte man mit 32 Bit, nicht nur die Töne: CDEFGAHC speichern, sondern auch noch welchem Instrument der Ton entspricht. Jetzt kann man sich aber vorstellen: In BMP's existiert eine Tabelle. Man könnte also eine Tabelle verwenden, wie bei BMP's und da wäre zu jedem Ton, der auch nicht zum Standardrepertoire gehört, ein Ton gespeichert. Diese Töne müssten nicht 32 Bit enthalten, sondern könnten mit einer Ende-Marke, eine Sequenz sein. Bei Liedern die sich wiederholen, würde das gehen. Umgekehrt, könnte man als Sequenz auch eine Stimme speichern.


Diese Fragen, mit der Musik interessieren mich aber gar nicht. Das erste was ich mache, ist das Programm schreiben, dass die Sterne und Vierecke und Kreise auf eine Fläche bringt, nach einem regulären Ausdruck.
Was ich mich aber frage: Was ist daran aus zu setzen, in einem Bild mit regulären Ausdrücken zu arbeiten. Klar, den Vergleich von den bereits existierenden, mit dem existierenden Bild ist einfach. Man guckt mit SQL in die Datenbank, in der reguläre Ausdrücke gespeichert sind und vergleicht im Bild anhand der existierenden regulären Ausdrücke. Klar ist es schwieriger, die regulären Ausdrücke zu erkennen, die in einem davor existierenden Bild sind. Aber: Letzten Endes, kann man das dem Computer überlassen. Man muss sich gar nicht fragen, welche regulären Ausdrücke er bevorzugt. Man füllt eine Datenbank mit 1.000.000.000 Einträgen von regulären Ausdrücken und durchsucht das neue Bild einfach nach einem jeden. Ein anderes Problem, wäre die Interpretation. Das könnte ein zweites Programm sein. Dann könnte man verschiedenste Sachen feststellen. Ist es das gleiche Gesicht, ist es ein Gesicht, ist die Helligkeit gleich groß, das zum Beispiel Rückschluss auf die Herkunft des Bildes deuten lässt. Man kann auch einfach daher gehen und alle Menschen vergleichen, die betrunken sind, oder alle, die gestern betrunken oder alle, die Lügen oder alle die Lächeln und man macht sich keine Sorge darüber, welcher reguläre Ausdruck jetzt gerade verglichen wird, oder, was der Computer da gerade tut. Er macht es ganz von alleine und vergleicht selbständig nach regulären Ausdrücken. Umgekehrt steht im zweiten Schritt die Interpretation an. Das ist aber eine Sache, die tut man entweder selber, oder aber, man lässt sie durch ein zweites Programm laufen. Wichtig ist: Sollte denn der Begriff regulärer Ausdruck bei einem Bild gar nicht existieren. Das glaube ich nicht. Man denke daran: Wenn man jemanden von 2m Entfernung aus derselben Höhe photographiert, oder aus ein 1m Entfernung, das Gesicht behält dieselbe Form. Und: Ein regulärer Ausdruck kann das liefern, egal wie der aussieht und egal, was für einen Menschen ein Gesicht bedeutet. Oder ein regulärer Ausdruck, kann ohne ein bestimmtes Programm zu verwenden, feststellen, dass vieles dasselbe ist, dass aber die Helligkeit durchaus größer ist. Man kann dafür ein Programm schreiben, was bei jedem Pixel den Unterschied von 2 feststellt, das wäre aber ein Programm, das nur das kann.


Jetzt machen wir die Sache noch besser: Zunächst mal drehen wir ADD und MUL um. Damit die Reihenfolge bei der Darstellung besser wirkt. Im nächsten Schritt machen wir noch etwas: Wir haben das Neutrale Element Kreis, 0, dann haben wir ein Dreieck als nächstes, dann kommt ein Quadrat, dann kommt ein Stern mit 5 Ecken und so weiter und so fort. Wenn man addiert schreibt man sie nebeneinander, wenn man multipliziert, bedeutet das, man schreibt den folgenden so oft hintereinander, wie der andere Ecken hat, der vordere. Um die Sache nicht zu verkomplizieren, macht man nicht 3*5=15, Dreieck und Stern, sondern man nimmt 5 Sterne für das Dreieck. Trotzdem bleibt man dabei, dass man bei der Multiplikation, die Figuren vorne und hinten anbringt, bei der Addition, immer hintereinander.
Wenn man total graphisch denken würde, könnte man an jeden Stern an seine Ecken, die vorherige Figur anbringen. Aber nicht seitlich, sondern auf die ecken selber. Dann könnte man einiges erzeugen.
Dieses Prinzip wäre aber vom Prinzip her umkehrbar. Wenn man zumindest Stern, Quadrat, Dreieck erkennt. Dieses Prinzip ist sicher umkehrbar, denn: Aus einem einfach regulären Ausdruck, wurde eine Figur erzeugt. Doch dieser reguläre Ausdruck ist einfach, denn man hat ihn ja angegeben. Das dabei aber interessantere Figuren zu Stande kommen, ist ja ersichtlich. Nun kann man sich aber fragen, wenn man das kann, kann man das sicher auch mit Punkten. So zum Beispiel mit einem Smiley. Man betrachtet einfach Punkte, die nahe beieinander liegen und vernachlässigt ein gewisses Rauschen, wenn ihre Farben ansonsten gleich sind. Dabei könnte man das Rauschen in dem regulären Ausdruck unterbringen. Niemand verbietet es einem, einen gewissen Prozentsatz ab zu ziehen. Wenn man aber, in dem regulären Ausdruck, Richtung und Farbe unterbringt, dann hat man Beispielsweise für eine Krümmung einen Ausdruck, der die Richtung angibt, dabei aber für jede Farbe einen einzelnen Teilausdruck angibt. Etwa E*100. E*100, wenn man noch die Richtung angibt, die dann verändert wird, wenn sie sich stark verändert, würde bedeuten, unter Angabe der Richtung, dass sich E, was auch immer das ist 100 Mal wiederholt. Das dieses Prinzip funktionieren müsste, zumindest in die eine Richtung sieht man an dem Vergleich von Text und Bild. Ein Bild ist 2.000.000 Bildpunkte groß, zum Beispiel. Das ist ein Verhältnismäßig kleiner Rahmen.
Ich werde aber die Sache anhand von Smiley's ausprobieren. Ich werde dabei reguläre Ausdrücke versuchen von Smiley's zu erstellen und dann werde ich versuchen, ob ich einfache traurige Smiley's von nicht traurigen unterscheiden kann, dabei soll die Farbe keine Rolle spielen, diese ist ein Rauschen, umgekehrt muss man bedenken: Eine komprimierte Information ist das, denn wenn zum Beispiel die Krümmung bei dem Mund, 50* dieselbe Tangente hat, oder die Krümmung gleichermaßen wächst, auch bei der Krümmung kann man ein Rauschen einbauen, dann kann man diese Information komprimiert ausdrücken. Was man mit Smileys machen kann, kann man mit allem anderen generell auch.


2017-10-21, ..., das sinnbildliche Rauschen, ..., motion bekommt einen großen Bruder

Jetzt zu unserem Smiley.
Im ersten Schritt geht man davon aus, es gibt zwei Farben. Welche sind egal. Farbe und Kontrastfarbe. Zum Beispiel Schwarz und Gelb, Schwarz und Rot und so weiter.
Das Problem wird aber mit regulären Ausdrücken gelöst.
Das erste, was wir machen, ist, das Bild absuchen. Die regulären Ausdrücke gelten für die Farbanteile, die geringer sind. Das heißt, existiert schwarz und gelb, dann zählen wir alle gelben Punkte und alle schwarzen Punkte. Sind die schwarzen Punkte in der Minderzahl, dann wird der reguläre Ausdruck für die schwarzen Punkte erstellt.
Das zweite, oder das allererste, was wir machen, ist: Wir lesen das Bitmap in ein zweidimensionales Array ein. Wir haben ein Bitmap, das ist eine Folge von Bytes. Diese liegen quasi linear hintereinander. Wir lesen aber jetzt anhand der Information, wie groß Breite und Länge ist, dieses lineare Array in ein zweidimensionales Array ein.
Der nächste Schritt besteht darin, eine Art "Rauschen" ein zu führen. Da wir nur zwei Farben verwenden, müssen wir das "Rauschen" in dem Falle nicht für die Farben verwenden, sondern für die Richtung. Dieses Rauschen ist aber fest eingerichtet. Nun ist das bei regulären Ausdrücken normal.
Man denke daran. Ein Buchstabe kann zwischen "A" <= "E" sein. Das heißt, auch in einem regulären Ausdruck ist es normal, oder gerade das ist normal, oder eigentlich der Sinn eines regulären Ausdruckes, nicht eben einen festen Buchstaben zu haben, wie A oder B, umgekehrt dafür alleine zum Beispiel eine Wiederholung, die alleine beliebig wäre. Ein regulärer Ausdruck könnte es aber schon sein, indem wir | (ODER) einführen und * (das heißt) eine beliebige Wiederholung. Auch das würde schon zum Ziel eines simplen, kleinen regulären Ausdrucks führen. Umgekehrt muss man sehen, dass man mit der Schreibweise I (ODER) nicht glücklich wird. Das heißt, wir schreiben nicht A|C, dafür, dass wir A oder C haben, und machen dies bei 12 Buchstaben. Sondern wir führen einen Bereich ein, also, das kleiner gleich: "A" <= "E". Dies überlassen wir aber dem Computer, genauso wie den regulären Ausdruck überhaupt. Wir schauen uns den gar nicht an. Sondern: Der Computer soll anhand des Ausdrucks feststellen, ob der Smiley lacht oder traurig ist. Der reguläre Ausdruck interessiert nicht.


Wie, soll das mit dem Smiley funktionieren?

Also

In dem regulären Ausdruck, speichern wir zwei Farben

R: Rot, Geld
S: Schwarz

oder

R: Schwarz
S: Rot, Gelb

oder wie auch immer.

Wenn die eine Farbe kommt, kommt ein R, wenn die andere Farbe kommt, kommt ein S

jetzt speichern wir die Anzahl, der R und S, die kommt

5*S, bedeutet 5 S
6*s, bedeutet 6 S
7*S, bedeutet 7 S

Dann kann der Ausdruck aussehen, wie folgt:
5*S, 6*R, 10*S

Diese 5, 6, 10, ..., wie auch immer, werden ersetzt durch n.
n ist eine Variable. Das heißt, hier können beliebig viele stehen.

Jetzt kommt der zweite Punkt,
der erste ist: Wir haben zwei Informationen gespeichert: R und S, die Farbe
n, die Länge

Jetzt kommt eine weitere Information:
Die Richtung. Die Richtung, gibt an in welcher Richtung der nächste Punkt liegt, der dieselbe Farbe hat.

So zum Beispiel
RRRR
RORR
RROR
RRRR
Das untere O, liegt -1 versetzt nach unten, als -1, -1.

Jetzt haben wir aber eine zweite Information: Nämlich, wir sind in einem Bild.
In einem Bild haben wir nicht automatisch einen Strich, der aus jeweils der Breite von einem Punkt besteht.

Also, haben wir neben der Richtung eine zweite Information.
Diese zweite Information besteht generell aus vier Informationen. Trotzdem ist es eine Information.
Diese eine Information besteht zunächst aus vier Informationen: Aber, die Information besteht aus 8 Informationen:
Norden, Nord-Ost, Ost, Süd-Ost, Süd, Süd-West, West, Nord-West
Aber wir sehen, zunächst mal gedacht, vier Informationen, aber 8 in der Realität.
Das sind 4 oder 8 Informationen, diese 4 oder 8 Informationen sind aber eine.
Diese eine Information gibt 8 Informationen preis. Umgekehrt, ist diese eine Information ein Vektor. Eine Information, die aus 8 Informationen besteht, muss nicht in Wirklichkeit eine Information sein, die 8 Informationen ist, sondern es ist ein Vektor.
Und dieser Vektor enthält 8 Elemente.

Jetzt bringen wir in unserem regulären Ausdruck folgende drei Informationen unter:

Farbe: Rot-Schwarz, Schwarz-Geld, Rot-Geld, Schwarz-Rot, ...

Die Länge n
Dann der Vektor, Vektor mit 8 Elementen, die benachbarten Felder.

Jetzt wie sollen die regulären Ausdrücke aussehen?

Jetzt ist meine Idee:

Zunächst Mal, die Verkettung, Concatenation.

ABC
bedeutet auf A, folgt B, folgt C

C(AC+B)D
bedeutet auf C folgt AC, oder B, folgt D
Also CAC oder CBD

Hüllebildung:

(AB)* = ABABAB...

Jetzt müssen wir wohl bei der Verkettung, Concatenation anfangen.

Wir sind es gewohnt, in einem Text, folgt Buchstabe auf Buchstabe
Das heißt:
ABCDEFG...

Jetzt sind wir im zweidimensionalen Raum.
Und: Wir haben von Vektoren gesprochen. Das heißt von einer Information, die aus 8 Informationen besteht, nämlich der Vektor, der benachbarten Felder.

Jetzt haben wir im Text

ABC

Hier folgt nach dem A, das B

umgekehrt kann man denken

AB1B2 Auf A folgt in der einen Richtung B1 in einer anderen Richtung B2

Nun haben wir 8 Richtungen.

Also
A[a1, a2, a3, a4, a5, a6, a7, a8]

Natürlich können wir nach jeden Buchstaben, so zu sagen, den folgenden speichern.

Dann schreiben wir wie im Text

ABCDEFG

aber wir haben ja Richtungen.
Also, kann man folgendes wie folgt interpretieren

Aa1a2

In die eine Richtung folgt a1, in die andere a2

Aber, warum das nicht so ausdrücken

A[b1, b2, b3, b4, b5, b6, b7, b8]
Das ist nichts als eine andere Ausdrücksweise, auch die Ausdrucksweise von oben, könnte man so interpretieren. Allerdings macht es das Leben leicht. Warum? Wir haben ja gar nicht vor, den regulären Ausdruck später zu lesen. Wir wollen das gar nicht wissen. Das erledigen zwei Programmteile für uns. Das eine ließt einen Smiley ein und erstellt einen Ausdruck, das andere ließt einen Smiley ein und vergleicht ihn mit dem Ausdruck. Was da jetzt in der "Datenbank" des Computer steht, wollen wir nicht wissen. Man kann so denken, der reguläre Ausdruck ist in der "Datenbank" untergebracht. Das interessiert uns nicht. Aber wir entwickeln das Programm und da müssen wir genau wissen, was wo ist.

Wenn die Richtung gleich bleibt, dann schreiben wir n.
Vereinfachen wir die Sache: kommen zwei, sagen wir vollkommen identische Punkte, nacheinander,
dann schreiben wir n = 2. Aber, sobald wir n = 2, schreiben wir n.
Das heißt für jedes n > 1, (2, 3, 4, ...) , schreiben wir autoamtisch n. n > 1, bedeutet, also 2, 3, 4, ... hier können beliebig viele Pixel folgen, die identisch sind. Das ist das Prinzip der Hüllenbildung.

Jetzt noch eine Frage: Wenn wir einen Ausdruck finden, es gibt ja viele Ausdrücke. Man kann aus einem regulären Ausdruck eine Information schließen, mit der man etwas in einer Folge findet. Jetzt ist die Frage, gibt es nicht viele reguläre Ausdrücke, die, dasselbe besagen? Das mag sein. Zum Beispiel ABABAAB kommt (AB)* ziemlich nahe. Nun haben wir aber gesagt, dass wir ab n>1 (AB)* einsetzen. Wenn wir jetzt eine Menge regulärer Ausdrücke finden könnten, dann ist das wahr. Aber ist das interessant? Wenn wir uns den regulären Ausdruck gar nicht anschauen, sondern das dem Programm überlassen, ist das sicher noch weniger interessant. Warum? Weil der Ausdruck kann sogar beschissen aussehen, soll heißen, der Ausdruck ist im Computer, kann uns doch egal sein, wie der aussieht, im schlimmsten Falle ist es eine Verschwendung von Speicherplatz. Und wie unlesbar und häßlich der aussieht kann uns egal sein, der Computer kann ihn interpretieren. Umgekehrt könnte man mehrere reguläre Ausdrücke finden, die dasselbe besagen, auch wenn unser Computer mit unserem Programm, immer nach demselben Schema vorgeht und somit immer auf dieselbe Art und Weise welche findet, dann kann uns das egal sein. Denn wenn mehrere reguläre Ausdrücke gefunden wurden, besagen sie dasselbe. Und somit kann man sie im zweiten Schritt, gleichermaßen anwenden.

Jetzt haben wir folgendes Problem:

Hüllenbildung. Das Entweder/Oder schließe ich aus.

Wir haben zwei Farben: Schwarz und Geld, Rot und Schwarz und so weiter.

Wenn wir aber genau zwei Farben haben, dann brauchen wir den regulären Ausdruck nur für eine Farbe auf zu stellen. Die andere Farbe vernachlässigen wir.
Wenn wir aber Entweder/Oder ausschließen, dann können wir uns die Operation A|B ersparen.
Dann haben wir zwei Operationen: AB, das heißt, auf A folgt B
Oder die Hüllenbildung *A. Das heißt, es folgen beliebig viele A: AAAAAA... Mehr als die drei Operationen gibt es so oder so nicht. Da wir eine ausgeschlossen haben, gibt es nur noch zwei. Diese sind wie gesagt, ABCD und *A Jetzt kann man dieses *A betrachten.
Wir sind bei unserem Vektor.
Da können wir jetzt auf ein Mal, zwei Dinge unterscheiden:
*A[b1, b2, b3, b4, b5, b6, b7, b8]
A[*b1, *b2, b3, b4, b5, *b6, b7, b8]
Das eine gilt dafür, dass der ganze Ausdruck wieder folgt, das heißt, dass der nächste Punkt eindeutig identisch ist. Für alle Punkte, b1 bis b8, und das bedeutet: Jeder dieser Punkte b1 bis b8 hat wiederum dieselben Eigenschaften wie A. Das heißt, jeder hat auch wieder solche Nachbarn.
Umgekehr bedeutet: A[*b1, *b2, b3, b4, b5, *b6, b7, b8], dass die Punkte b1, b2, b6, dieselben Eigenschaften haben, wie A, aber nicht b3, b4, b5, b7, b8

Jetzt kann man die Sache als Baum darstellen:

A[B[c1, c2, c3, c4, c5, c6, c7, c8],b2, b3, b4, b5, b6, b7, b8]
Das Sternchen wiederum bedeutet nur: Hier kann bis zu dem Unterknoten, der im Baum dargestellt ist und ein Unterknoten ist, beliebig oft, der eigentliche Knoten stehen.
Doch, jetzt ist die Sache realtiv klar:


http://www.talkortell.de/smiley01.c


So, ich bin jetzt mit meinem Programm so weit:
Siehe, letzter Beitrag:
Ich benutze nach wie vor BMP's. Windows *.bmp's. Ich benutze keine Rohdaten. Jetzt ist mir aufgefallen: Wenn ich eine Datei unter GIMP zum Beispiel speichere, also einen Smiley und ihn nach BMP konvertiere, dann enthält die Datei mehr als zwei Farben, auch wenn im Bild nur zwei Farben zu sehen sind. Ich habe aber als "Postulat", dass nur zwei Farben enthalten sind. Also habe ich das Problem jetzt so gelöst. Das Programm geht jede einzelne Farbe durch. Es wird unterschieden zwischen der Mehrheit der Farben und der Minderheit der Farben. Ich habe ja zwei Farben. Das war das "Postulat". Ich sage jetzt, die Farbe die in der Mehrheit auftritt ist die eine Farbe, alle anderen Farben in der Minderheit sind die andere Farbe. Dazu zähle ich das Auftauchen der Farben im Bild. Ich gehe jeden Punkt durch, wenn er nicht schon verglichen wird (sonst haben wir es mit extrem langen Programmlaufzeiten zu tun), sondern ich vergleiche jeden Punkt, wenn seine Farbe nicht schon bekannt ist und zähle das Auftreten der Farbe an dem Punkt im weiteren Bild. Wenn ich damit fertig bin, nehme ich die Farbe die am häufigsten auftritt als die eine Farbe.
Im nächsten Schritt ersetze ich jede Farbe, die nicht der Mehrheit angehört, durch eine bestimmte Farbe, die von der Mehrheit verschieden ist.
Bislang öffne ich also eine BMP-Datei. Und ich zähle das Auftreten der Farben und ersetze es.
Am Schluss wird die Sache so aussehen: Ich rufe das Programm auf: "programmname bild1.bmp bild2.bmp". Dann gibt das Programm aus, ob die Bilder das identische aussagen oder nicht.


http://www.talkortell.de/smiley02.c


letzter Beitrag:
In diesem Fall starten wir jetzt in der letzten Schleife, die noch nicht fertig ist, den eigentlichen Algorithmus. Die letzte Schleife ist noch nicht ausgefüllt, hier steht der Algorithmus. Man geht an jeden Punkt, der von der Farbe mit der Minderheit ist und durchläuft hier (das ist ja selber eine Schleife, die zu jedem Punkt geht), eine weitere Schleife, die den Algorithmus darstellt: Hier wird von jedem Punkt ein Mal aus der Algorithmus gestartet, dass nämlich das Suchmuster erstellt wird. Oder eigentlich der Ausdruck vom Suchmuster, der aber ja uns nicht bekannt ist: Den schauen wir nicht an, der steht nur im Programm.


http://www.talkortell.de/smiley03.c


etzt, kann man auch von einem Rauschen sprechen, in einem ganz anderen Sinne.
Jetzt hatten wir es mit analogen Rauschen, digitalen Rauschen zu tun. Beim analogen Rauschen spielen zwei Dinge eine Rolle: Mischer (Mischung bedeutet zwei Signale werden miteinander gemischt, dabei entweder additiv oder multiplikativ), beim additiven Mischen kann man auch von einer generellen Pegelanpasssung reden. Wenn die Impedanz oder der Pegel nicht stimmt, dann gibt es auch ein Rauschen. Das führt nicht automatisch dazu, dass das Bild einfach heller wird, sondern es kann zu Verzerrungen führen. Beim digitalen Rauschen kann man sogar zum selben Ergebnis kommen, aber zunächst hier sind beim Rauschen zwei Sachen zu unterscheiden: Das eine ist das Rauschen im Punkt. Hier kann ein Wert von +2, einen Unterschied machen und ist also ein Rauschen. Dann kann man sagen, bei jedem Punkt, gilt +2. Das ist ein Rauschen, das für jeden Punkt gleich ist für das ganze Bild. Nun kann man einen Prozentsatz einführen, in wie weit für ein Punkt ein Rauschen besteht: wenn Werte von 0 bis 255 zugelassen sind, ein Punkt hat den Wert 100, der andere 98, dann herrscht ein Rauchen für den Punkt von 2%. Umgekehrt kann man alle Punkte zusammensetzen und am Ende hat man einen Durchschnittswert für das gesamte Rauschen. Umgekehrt.
Jetzt haben wir es mit analogen Rauschen, digitalen Rauschen zu tun, jetzt kommt der Smiley. Hier haben wir ein Rauschen, das bezieht sich auf das gesamte Bild. Hier haben wir also ein Rauschen im Ausdruck. Der eine grinst, der andere ist traurig, das ergibt ein Rauschen. Und zwar, was die Aussage des Bildes betrifft. Feststellen kann man das aber nicht darüber, dass man wie bei dem Linux-Programm "motion" vorgeht. Denn dieses stellt zum Beispiel ein farbliches Rauschen fest. Umgekehrt kann man jetzt sagen: In einem Text ist ein typisches Verhalten nach einem Suchmuster zu suchen.
Das eine wäre, wir rufen einen Texteditor auf, zum Beispiel "kate" unter KDE, Linux. Dann suchen wir überall nach dem Wort, "Hallo Welt". Das kann mehrfach auftauchen oder aber es kann auch von uns ersetzt werden, durch "hello world". Wir können es dabei jedes Mal einzeln ersetzen und das nächste suchen, die andere Methode wäre es im gesamten Text zu ersetzen. Jetzt gibt es hier die typischen Algorithmen. Der erste wäre der Brute-Force-Algorithmus. Dann kommen Algorithmen von Knuth-Morris-Pratt und B...
Das wäre, wenn wir ganz konkretes Suchmuster suchen.
Eine andere Methode wäre die Eingabe von regulären Ausdrücken. Hier spezifizieren wir zum Beispiel, dass wir eine Zeichenfolge, AB, AAB, AAAB, AAAAB, AAAAAB haben, aber nicht indem wir jeden Ausdruck eingeben, sondern in dem wir allgemein für alle Ausdrücke *AB schreiben.
Dann kann man das natürlich auf den Zweidimensionalen Raum ausdehnen.
Darauf bezieht sich der letzte Beitrag mit seinem Quelltext, hier sieht man eine Funktion make_pattern.


http://www.talkortell.de/smiley04.c


http://www.talkortell.de/smiley05.c


http://www.talkortell.de/patternmatching.c


http://www.talkortell.de/patternmatching2.c


http://www.talkortell.de/patternmatching3.c


http://www.talkortell.de/patternmatching4.c


Nächster Tag

http://www.talkortell.de/smiley06.c


So, weit bin ich mit dem Code bisher (Smiley) Jetzt mache ich am Besten einen Versuch. Ohne Speicherplatz an zu fordern, mache ich die Funktionsaufrufe, ohne Datenstruktur. Also die Rekursiven zu Erstellung der eigentlichen Datenstruktur, um zu gucken, ob es mit diesen rekursiven Funktionsaufrufen klappt.


http://www.talkortell.de/smiley07.c


Wenn man sich den letzten Beitrag anschaut, scheint es nicht an der Menge und Häufigkeit der rekursiven Funktionsaufrufe zu liegen. Ich habe nämlich jetzt die Menge der rekursiven Funktionsaufrufe stark reduziert, indem, ich MAX_LINE_HEIGHT und MAX_LINE_WIDTH stark verkleiner habe. Der Speicherzugriffsfehler findet trotzdem noch statt.


http://www.talkortell.de/smiley08.c





http://www.talkortell.de/smiley09temp.c


Es zeigt sich an diesem Beispiel eindeutig, dass es sich um einen Speicherzugriffsfehler, wegen "to deeply nested" handelt. Denn ich habe hier die Funktion make_pattern, alleine getestet, lässt man nur 3 IF's steht funktioniert sie bei MAX_LINE_HEIGHT = 3 und MAX_LINE_WIDTH = 3, gerade noch. Ab 4 bis 5 IF's scheitert die Funktion.
Deswegen muss ich mir einen nicht rekursiven Algorithmus ausdenken. Ich muss jetzt eine nicht rekursive alternative Ausdenken.

Ich weiß, schon, wie ich das Problem löse. Ich gehe zu jedem Punkt
for(k = 0; k < biHeight; k++) {
for(l = 0; l < biWidth; l++) {
... Dann gehe ich von jedem der Punkte ein Mal schräg nach, gerade nach oben, schräg links, rechts, ...
Dann zähle ich die Anzahl der Punkte, die ich gehen kann, bei der also die Farbe gleich ist.



Also: An jeden Ort gehen:
for(k = 0; k < biHeight; k++) {
for(l = 0; l < biWidth; l++) {
...
Dann von jedem der Punkte aus:
Nord, Nord-Ost, Ost, Süd-Ost, Süd, Süd-West, West, Nord-Ost
und zähle, die Anzahl der Punkte, bei denen das gleich bleibt.
Dabei zähle ich die Schritte mit. Ist n > 1, dann wird * gesetzt. Ist n = 1. Dann gilt die Regel (A|B): Wir wissen wir haben zwei Farben A und B.
Wir haben die Regeln *A, A|B, A und B. Das heißt, ich für n > 1 setze ich *, da ich eine Art "Rauschen habe" setze ich für n=1 (A|B) und für n = 0, setze ich B oder 0 ein.


http://www.talkortell.de/smiley10.c





http://www.talkortell.de/smiley11.c





http://www.talkortell.de/smiley11.c


So, jetzt ist diese Routine fertig. Jetzt kommt der zweite Schritt. Wir legen das erstellte Muster, auf jede Stelle buffer[k][l], des zweiten Musters.


http://www.talkortell.de/smiley13.c


Was nachher entscheidend ist, aber das kommt erst noch. Wenn wir zwei Punkte NORD_OST haben, und hinter diesen folgt in NORD_OST, beliebig viele Punkte, dann haben beiden N gespeichert. Wenn man dieses nun auf das Vergleichsbild legt, dann ist das Problem: Das zweite Bild kann zwar breiter sein, aber nicht schmaler. Denn wir speichern, wenn es "weit" nach NORD_OST geht für jeden Punkt in NORD_OST ein n bzw. *. Jetzt auch für die beiden benachbarten Punkte. Es wäre notwendig, alle Punkte, bei denen n steht oder * (Sternchen) zu einem zusammen zu fassen. Denn der erste Punkt nach NORD_OST hat n oder *, der zweite n oder *, der dritte, diese Reihe sollte man zu einem zusammenfassen.


So, funktioniert die Sache auch ohne Speicherzugriffsfehler! Achtung! Wenn MAX_LINE_HEIGHT und MAX_LINE_WIDTH zu groß gewählt sind, dann gibt es wieder einen Speicherzugrifffehler! Das liegt aber eindeutig daran. Macht man sie zu groß gibt es einen, macht man sie kleiner gibt es keinen. 320 jeweils gibt keinen. Das liegt aber daran.


So, im nächsten Schritt, legen wir die beiden Bilder aufeinander drauf. Dafür schreiben wir eine Funktion cmp_pattern. Die eine Möglichkeit besteht jetzt darin, das Muster direkt auf das zweite Bild an zu wenden. Oder wir erstellen ein Muster vom ersten Bild und vom zweiten Bild und vergleichen die beiden entstanden Muster.


Wir sind faul! Wir haben zwei Dateien und beide müssen gelesen werden. Dafür haben wir die Dateizeiger fp und fp1. Jetzt ist das Problem, da beide gelesen werden, müssen wir jetzt nicht nur fp und fp1 verdoppeln, sondern: Wir müssen alles verdoppeln: biWidth, biHeight, ... sind wir verrückt? Nein, wir machen das anders: Wir haben ja nun das Muster erstellt: Wir brauchen in fp nichts mehr zu lesen. Also schließen wir fp von der ersten Datei und öffnen die zweite Datei wieder unter fp mit demselben Daten. Das Muster von der ersten Datei ist ja schon da. Die erste Datei wird geschlossen, wir kopieren alles von dem ersten Quelltext zur Behandlung der ersten Datei und nun haben wir wieder einen Buffer, denselben, aber diesmal gefüllt mit dem Inhalt der zweiten Datei. Wir erstellen jetzt auch nicht großartig ein zweites Muster, sondern wenden das erste Muster von der ersten Datei gleich direkt auf die zweite Datei an. Wir behalten uns aber die Erstellung von zwei Mustern vor. Wir schreiben zwei Funktionen pattern_cmp und patter_cmp2. Die erste wendet das Muster von der ersten Datei direkt auf die zweite Datei an, die zweite Funktion benutzt zwei Muster, die miteinander verglichen werden. Der Vorteil von zwei Mustern ist eventuell die automatische Beseitigung, des unten genannten Problems: Gehen wir nach NORD_OST und folgen hier eine Menge Punkte. Dann ist der Punkt 1 nach NORD_OST, n oder *, der zweite nach NORD_OST, n oder * und so weiter. Was ist wenn dieses Prinzip vorliegt, im zweiten Bild aber verkürzt wird? Wenn man zwei Muster hat, löst sich dieses Problem einfach: Man vergleicht in die eine Richtung und in die andere, aber nicht jedes Muster, erst in die eine und dann in die andere, sondern von jedem Punkt aus, erst in von dem einem zum anderen, dann von dem anderen zum ersteren.


Die Geschichte ist relativ einfach: Die Funktion cmp_pattern ist quasi dasselbe wie make_pattern. Nur: Es werden zwei Bilder verglichen. Der Buffer ist diesmal nicht das Muster. Der Buffer ist von der einen Datei, das Muster von der anderen. Das Ergebnis von davor. Nun machen wir folgendes: Anstatt, dass wir jedes Mal, zuweisen: ... NORTH_EAST = n oder wie auch immer, machen wir hier einen Vergleich. Und wir führen zwei Zähler. Diese drücken im Prinzip das Rauschen aus. Wir führen zwei Zähler. Der eine heißt positive_count, der andere negative_count. Jedes Mal, wenn das Muster übereinstimmt, machen wir positive_count++, ansonsten negative_count++. Dieses drückt eine positive Übereinstimmung ein Rauschen dar, also wo etwas nicht übereinstimmte. Ein Zähler für das Rauschen, mit Übereinstimmung und Nicht-Übereinstimmung.


Und wir führen zwei Zähler. Diese drücken im Prinzip das Rauschen aus. Wir führen zwei Zähler. Der eine heißt positive_count, der andere negative_count. Jedes Mal, wenn das Muster übereinstimmt, machen wir positive_count++, ansonsten negative_count++. Dieses drückt eine positive Übereinstimmung ein Rauschen dar, also wo etwas nicht übereinstimmte. Ein Zähler für das Rauschen, mit Übereinstimmung und Nicht-Übereinstimmung.





http://www.talkortell.de/smiley14temp.c





http://www.talkortell.de/smiley15.c


So, jetzt habe ich diesen Programmquelltext und der stürzt auch nicht ab. Ich habe den Negativen Count und den Positiven Count ausgedruckt, leider noch kein befriedigendes Ergebnis:
positive count: -1460781344, negative count: -1461621024
Bei einem anderem Bild kam:
positive count: -405227584, negative count: -406067264
Aber das kann folgende Ursachen haben: Zum Beispiel, die Zahlen die hier stehen sind ja negativ. Ich habe unsigned verwendet, printf druckt aber mit Vorzeichen aus %i und %u. Außerdem sollte ich als Zähler vielleicht long ausdrucken.
Ich probiere es gleich mal aus:

Da kommt raus:
positive count: 816463776, negative count: 815624096
Vielleicht sollte ich es mit long probieren.
Bei long kommt raus:
positive count: 140721560169952, negative count: 140721559330272
Immer noch kein befriedigendes Ergebnis.

Ah ich weiß, was der Fehler war:
Das ist eindeutig so!!!!
printf("positive count: %li, negative count: %li\n");
Da steht
printf("positive count: %li, negative count: %li\n");
Das kann gar nicht funktionieren, weil die Variablen bei printf sind gar nicht angegeben. Das sind irgendwelche Werte, aber nicht die Werte der Variablen, weil bei printf sind die Variablenwerte nicht angegeben.

Da da da da!
Jetzt kommt was befriedigendes Raus!!! Da, da, da, da... Es war printf (printf konnte gar nichts befriedigendes ausgeben!) Und nun schaut man sich das Ergebnis an:
positive count: 605472, negative count: 0

Das Ergebnis, dies Mal ohne den Schnitzer von printf:
positive count: 605472, negative count: 0

Es konnte nicht gehen!!! Es konnte nicht gehen! Selbst, wenn irgendetwas falsch war, es konnte nicht gehen. Selbst wenn, etwas falsch wäre, es ging nicht: Weil, selbst wenn etwas falsch wäre, und selbst wenn etwas nicht stimmte, das Ergebnis, war alles nur nicht das Ergebnis. Printf hätte selbst bei einem falschen Ergebnis irgendetwas nur nicht das Ergebnis ausgegeben. Denn printf war gar nicht an das Ergebnis gebunden.

Ne, da ist noch ein Fehler drin:
Jetzt spuckt es ständig aus:
positive count: 605472, negative count: 0
Aber, ich habe ein Bild Leicht verändert und das Programm hat das nicht erkannt.