JPEG Bilder die 2te
-
Enno schrieb:
Das mit dem int quantTable[0][64] mach ich jetzt also muss dazu nicht unbedingt was gesagt werden
Doch, muss schon. Deutlicher als knivil: Was bewirkt das 0 hier?
Ein paar Bemerkungen zu deinem letzten Code:
- Warum castest du eigentlich nach
char, was schon eincharist? Ohnehin solltest du keine C-Casts, sondernstatic_castund die anderen C++-Operatoren benutzen. - Deine
DQT-Klasse verletzt die Regel der Grossen Drei (angenommen, Konstruktor/Destruktor wären richtig benannt). - Würdest du STL-Container statt
new[]unddelete[]verwenden, wäre die Regel der Grossen Drei automatisch erfüllt, und du hättest sonst einige Probleme weniger. - Verwende die Konstruktor-Initialisierungsliste statt Zuweisungen.
- Im Weiteren hast du nicht benutzte
#includes. - Explizite Vergleiche auf
== truesind unnötig. - Statt
if (x) return true; else return false;schreibereturn x;. - Bevorzuge in For-Schleifen Prä-Inkrement über Post-Inkrement, bei Iteratoren kann der Unterschied relevant werden.
- Zeiger auf Zeiger sind in C++ fast immer unnötig. Wahrscheinlich kann man das besser lösen.
- Warum castest du eigentlich nach
-
Nexus schrieb:
Doch, muss schon. Deutlicher als knivil: Was bewirkt das 0 hier?
Ehm also was ich dort machen wollte ist das ich ein 2d Array haben möchte. Die 0 hab ich dort eingetragen weil mir gesagt wurde, wenn ich diese dort reinschreibe ich so viele Spalten erhalte wie ich brauche. Mal 2 Spalten mal 4 Spalten.
**Ein paar Bemerkungen zu deinem letzten Code:
[list][*]Warum castest du eigentlich nachchar, was schon eincharist? Ohnehin solltest du keine C-Casts, sondernstatic_castund die anderen C++-Operatoren benutzen.
**
Hab ich vergessen..**[*]Deine
DQT-Klasse verletzt die Regel der Grossen Drei (angenommen, Konstruktor/Destruktor wären richtig benannt).
***[]Würdest du STL-Container stattnew[]unddelete[]verwenden, wäre die Regel der Grossen Drei automatisch erfüllt, und du hättest sonst einige Probleme weniger.
***[]Verwende die Konstruktor-Initialisierungsliste statt Zuweisungen.
**
Das schau ich mir jetzt noch einmal genauer an.**[*]Im Weiteren hast du nicht benutzte
#includes.
**
Hoppla.**[*]Explizite Vergleiche auf
== truesind unnötig.
**
Warum?[*]Statt
if (x) return true; else return false;schreibereturn x;.
ich weiß nicht aber für mich leuchtet das nicht ein warum ich dareturn x;machen soll. Ich will ja nicht x haben sondern solange true zurück geben bis**DQTalso*DQT[]komplett durch ist. Ich hab also mehrere Zeiger die ich mit einem index durchlaufen kann. So war der Plan.**[*]Bevorzuge in For-Schleifen Prä-Inkrement über Post-Inkrement, bei Iteratoren kann der Unterschied relevant werden.
**
Verstehe ich nicht, wo soll das den dort grade besser sein und warum ist das allgemein besser?**[*]Zeiger auf Zeiger sind in C++ fast immer unnötig. Wahrscheinlich kann man das besser lösen.**Ich denke das hab ich oben schon gesagt bei dem return.
-
Enno schrieb:
**[*]Explizite Vergleiche auf
== truesind unnötig.
**
Warum?Weil du doch eh schon einen boolschen Wert hast. Warum testest du den nochmal auf == true?
Das ändert den boolschen Wert nicht und macht es nur schwerer lesbar.Enno schrieb:
[*]Statt
if (x) return true; else return false;schreibereturn x;.
ich weiß nicht aber für mich leuchtet das nicht ein warum ich dareturn x;machen soll. Ich will ja nicht x haben sondern solange true zurück geben bis**DQTalso*DQT[]komplett durch ist. Ich hab also mehrere Zeiger die ich mit einem index durchlaufen kann. So war der Plan.Das Gleiche. Du hast schon einen boolschen Wert! Gib den doch zurück (mit ! in deinem Fall).
Enno schrieb:
**[*]Bevorzuge in For-Schleifen Prä-Inkrement über Post-Inkrement, bei Iteratoren kann der Unterschied relevant werden.
**
Verstehe ich nicht, wo soll das den dort grade besser sein und warum ist das allgemein besser?Das ist dort egal, aber warum solltest du dir die ungünstigere Variante angewöhnen?
Wie gesagt, wenn mal über Iteratoren iterierst, ist der Prä-Inc besser, da Post-Inc eine lokale Kopie erstellt.
-
Enno schrieb:
Ehm also was ich dort machen wollte ist das ich ein 2d Array haben möchte. Die 0 hab ich dort eingetragen weil mir gesagt wurde, wenn ich diese dort reinschreibe ich so viele Spalten erhalte wie ich brauche. Mal 2 Spalten mal 4 Spalten.
Wer hat das gesagt? Das ist nämlich Schwachsinn. Arrays sind in C++ nicht veränderbar in ihrer Grösse. Dazu könnte man eben STL-Container nehmen.
Enno schrieb:
**[*]Explizite Vergleiche auf
== truesind unnötig.
**Warum?Du schreibst auch nicht
if ((2 < 3) == true), wieso alsoif (marker->nextIndex() == true)? Davon abgesehen ist "nextIndex" ein verwirrender Name, niemand würde hier einenbool-Typen erwarten.Enno schrieb:
Ich will ja nicht x haben sondern solange true zurück geben bis
**DQTalso*DQT[]komplett durch ist.Nimm nicht alles wörtlich,
xwar nur ein Platzhalter für beliebige boolsche Ausdrücke.Enno schrieb:
Ich denke das hab ich oben schon gesagt bei dem return.
"Mehrere Zeiger mit einem Index durchlaufen" verstehe ich nicht, wozu brauchst du überhaupt mehrere Zeiger? Wieso reicht eine einfache Indirektion nicht? Denk dran, du kannst 2D-Arrays auch auf 1D-Arrays abbilden und dann Indizes umrechnen. In deinem Fall der Quantisierungstabellen könnte man sich sogar eine kleine Klasse überlegen, oder aber mindestens eine globale
at(array, x, y)-Funktion, die Indizes auf 1D abbildet.Enno schrieb:
Verstehe ich nicht, wo soll das den dort grade besser sein und warum ist das allgemein besser?
a = i++ist semantisch äquivalent zu
auto copy = i; ++i; a = copy;Bei Built-In-Typen spielt das zwar keine Rolle, wenn du den Ausdruck nicht weiterverwendest. Aber besser, du gewöhnst dir das gleich richtig an, Prä-Inkrement kostet ja nichts.
-
Nexus schrieb:
Enno schrieb:
Ehm also was ich dort machen wollte ist das ich ein 2d Array haben möchte. Die 0 hab ich dort eingetragen weil mir gesagt wurde, wenn ich diese dort reinschreibe ich so viele Spalten erhalte wie ich brauche. Mal 2 Spalten mal 4 Spalten.
Wer hat das gesagt? Das ist nämlich Schwachsinn. Arrays sind in C++ nicht veränderbar in ihrer Grösse. Dazu könnte man eben STL-Container nehmen.
Ok dann wurde mir mist erzählt!!! -.-
Danke.Nexus schrieb:
Enno schrieb:
**[*]Explizite Vergleiche auf
== truesind unnötig.
**Warum?Du schreibst auch nicht
if ((2 < 3) == true), wieso alsoif (marker->nextIndex() == true)? Davon abgesehen ist "nextIndex" ein verwirrender Name, niemand würde hier einenbool-Typen erwarten.Ok das leuchtet ein. Danke.
Nexus schrieb:
Enno schrieb:
Ich will ja nicht x haben sondern solange true zurück geben bis
**DQTalso*DQT[]komplett durch ist.Nimm nicht alles wörtlich,
xwar nur ein Platzhalter für beliebige boolsche Ausdrücke.Enno schrieb:
Ich denke das hab ich oben schon gesagt bei dem return.
"Mehrere Zeiger mit einem Index durchlaufen" verstehe ich nicht, wozu brauchst du überhaupt mehrere Zeiger? Wieso reicht eine einfache Indirektion nicht? Denk dran, du kannst 2D-Arrays auch auf 1D-Arrays abbilden und dann Indizes umrechnen. In deinem Fall der Quantisierungstabellen könnte man sich sogar eine kleine Klasse überlegen, oder aber mindestens eine globale
at(array, x, y)-Funktion, die Indizes auf 1D abbildet.Das Problem ist das ich den gleichen(nicht selben) Zeiger habe. Es gibt nun mal mehrere Qunatisierungstabellen.
Nexus schrieb:
Enno schrieb:
Verstehe ich nicht, wo soll das den dort grade besser sein und warum ist das allgemein besser?
a = i++ist semantisch äquivalent zu
auto copy = i; ++i; a = copy;Bei Built-In-Typen spielt das zwar keine Rolle, wenn du den Ausdruck nicht weiterverwendest. Aber besser, du gewöhnst dir das gleich richtig an, Prä-Inkrement kostet ja nichts.
Ok aber ich versteh den Sinn noch nicht was dadran so toll ist. Sorry aber für mich sind das einfach mehr Zeilen.
Also wo gewinne ich da einen Vorteil?Ich danke dir Nexus das du mir hier so viel hilfst.

-
...
-
Enno schrieb:
Das Problem ist das ich den gleichen(nicht selben) Zeiger habe. Es gibt nun mal mehrere Qunatisierungstabellen.
Ja, aber warum nicht einen (nicht zwei) Zeiger pro Tabelle? Oder gleich sowas wie
std::vector<QuantizerTable>, wo alle Tabellen abgespeichert sind? Ich sehe nicht ganz, wieso du**brauchst...Enno schrieb:
Ok aber ich versteh den Sinn noch nicht was dadran so toll ist. Sorry aber für mich sind das einfach mehr Zeilen.
Also wo gewinne ich da einen Vorteil?Du würdest ja nur
++istatti++schreiben, es ist nicht mehr Schreibaufwand. Der Code mit den 3 Zeilen sollte nur die Semantik voni++verdeutlichen. Da passiert eben mehr als bei++i, wobei du dieses "Mehr" nur dann brauchst, wenn du den Ausdruck auch weiterverwendest (z.B.a = i++schreibst).
-
Swordfish schrieb:
volkard schrieb:
Der steht komplett vor einer Wand. Die ist unerklimmbar.
SeppJ schrieb:
Dir wurde hier wieder und wieder gesagt, dass du dich mit deinem Projekt vollkommen übernimmst.
Alle schrieb:
*bemühte Hilfestellung*
Enno schrieb:
*Bahnhof*
q.e.d.
Wenn du das meinst oder auch alle anderen. Ich hab schon extrem viel an diesem Projekt gelernt und gebe trotzdem nicht auf egal wie oft ihr meint ich schaff das nicht. Mir macht es Spaß und es interessiert mich!
Mach es dann lieber wie die anderen und sei einfach leise. Ich versteh einfach diese Einstellung nicht. -.- Ich versuch das alles zu lernen und die meisten von euch reden das nur schlecht.
Aber hey ... *woopwoop*
Nexus schrieb:
Enno schrieb:
Das Problem ist das ich den gleichen(nicht selben) Zeiger habe. Es gibt nun mal mehrere Qunatisierungstabellen.
Ja, aber warum nicht einen (nicht zwei) Zeiger pro Tabelle? Oder gleich sowas wie
std::vector<QuantizerTable>, wo alle Tabellen abgespeichert sind? Ich sehe nicht ganz, wieso du**brauchst...Ok ich versuch das noch einmal zu erklären.
Ich hab mehrere Zeiger die in einem Dokument auf das gleiche zeigen so:ff db .. hex zahlen .. ff db .. hex zahlen ..Jetzt speicher ich halt alle Zeiger in dem **DQT und in meiner buildQT(); ruf ich diese nach einander auf, um dadraus die verschieden Quantisierungtabellen zu bauen. Welche ich dann in dem Array speicher möchte.
Nexus schrieb:
Enno schrieb:
Ok aber ich versteh den Sinn noch nicht was dadran so toll ist. Sorry aber für mich sind das einfach mehr Zeilen.
Also wo gewinne ich da einen Vorteil?Du würdest ja nur
++istatti++schreiben, es ist nicht mehr Schreibaufwand. Der Code mit den 3 Zeilen sollte nur die Semantik voni++verdeutlichen. Da passiert eben mehr als bei++i, wobei du dieses "Mehr" nur dann brauchst, wenn du den Ausdruck auch weiterverwendest (z.B.a = i++schreibst).Ok jetzt hab ich es gerafft.

Würdest du das immer benutzen?
-
Man geht als Standard davon aus, dass man ++i nutzt. i++ nutzt man nur dann wenn mans wirklich braucht, weil es halt teurer ist.
-
Skym0sh0 schrieb:
Man geht als Standard davon aus, dass man ++i nutzt. i++ nutzt man nur dann wenn mans wirklich braucht, weil es halt teurer ist.
Was meisnt du den jetzt mit teurer?? XD
-
Langsamer und speicherintensiver
-
Enno schrieb:
Wenn du das meinst oder auch alle anderen. Ich hab schon extrem viel an diesem Projekt gelernt und gebe trotzdem nicht auf egal wie oft ihr meint ich schaff das nicht. Mir macht es Spaß und es interessiert mich!
Mach es dann lieber wie die anderen und sei einfach leise. Ich versteh einfach diese Einstellung nicht. -.- Ich versuch das alles zu lernen und die meisten von euch reden das nur schlecht.Ich denke nicht, dass das von den meisten so gemeint ist, wie du das interpretierst. Ich finde es zb. schön, dass du das alles lernen willst, und würde das auch unterstützen. Ich würde dir auch nie empfehlen, aufzugeben. Stattdessen würde ich dir empfehlen erstmal die Grundlagen zu lernen und das Projekt dann fortzuführen, weil ich denke, dass du dann in weniger Zeit mehr lernen würdest und mehr Spaß dabei hättest.
Falls das jetzt aber immernoch missverständlich von mir ausgedrückt war:
Wenn beim Turnen jemand zu mir kommt und möchte, dass ich ihm dabei helfe Schraubensalto zu lernen, dafür aber meiner Meinung nach absolut noch nicht weit genug ist (Er kann noch gar keinen Salto ohne Schraube.), erkläre ich ihm, dass er erstmal einen guten normalen Salto lernen soll, um dann darauf sein Schraubending aufzubauen, weil es so einfach schneller geht, er nicht so oft auf den Kopf fällt und die Schraube hinterher schöner aussehen wird.
Es geht nicht darum, jemanden von seinem Ziel abzubringen, sondern darum, ihm einen besseren Weg zu diesem Ziel zu zeigen. Verstehst du, was ich meine?
-
Dobi schrieb:
Enno schrieb:
Wenn du das meinst oder auch alle anderen. Ich hab schon extrem viel an diesem Projekt gelernt und gebe trotzdem nicht auf egal wie oft ihr meint ich schaff das nicht. Mir macht es Spaß und es interessiert mich!
Mach es dann lieber wie die anderen und sei einfach leise. Ich versteh einfach diese Einstellung nicht. -.- Ich versuch das alles zu lernen und die meisten von euch reden das nur schlecht.Ich denke nicht, dass das von den meisten so gemeint ist, wie du das interpretierst. Ich finde es zb. schön, dass du das alles lernen willst, und würde das auch unterstützen. Ich würde dir auch nie empfehlen, aufzugeben. Stattdessen würde ich dir empfehlen erstmal die Grundlagen zu lernen und das Projekt dann fortzuführen, weil ich denke, dass du dann in weniger Zeit mehr lernen würdest und mehr Spaß dabei hättest.
Falls das jetzt aber immernoch missverständlich von mir ausgedrückt war:
Wenn beim Turnen jemand zu mir kommt und möchte, dass ich ihm dabei helfe Schraubensalto zu lernen, dafür aber meiner Meinung nach absolut noch nicht weit genug ist (Er kann noch gar keinen Salto ohne Schraube.), erkläre ich ihm, dass er erstmal einen guten normalen Salto lernen soll, um dann darauf sein Schraubending aufzubauen, weil es so einfach schneller geht, er nicht so oft auf den Kopf fällt und die Schraube hinterher schöner aussehen wird.
Es geht nicht darum, jemanden von seinem Ziel abzubringen, sondern darum, ihm einen besseren Weg zu diesem Ziel zu zeigen. Verstehst du, was ich meine?
Das ist nett geschrieben!

Ich verstehe das auch voll und ganz. Trotzdem hab ich denke ich oft genug klar gemacht das ich nun mal mein Schraubending direkt zu lernen. Ich weiß ist vielleicht nicht das beste aber ich hab ziemlich bock auf dieses Projekt.
-
Enno schrieb:
Trotzdem hab ich denke ich oft genug klar gemacht das ich nun mal mein Schraubending direkt zu lernen.
Allerdings wirst du hier wohl niemanden finden, der das Coachen dafür übernimmt (jedenfalls nicht ohne entsprechende pekuniäre Kompensation).
-
camper schrieb:
Enno schrieb:
Trotzdem hab ich denke ich oft genug klar gemacht das ich nun mal mein Schraubending direkt zu lernen.
Allerdings wirst du hier wohl niemanden finden, der das Coachen dafür übernimmt (jedenfalls nicht ohne entsprechende pekuniäre Kompensation).
Das kann sein, trotzdem Fragen kostet ja nichts und man darf ruhig mehr auf die Fragen eingehen. Wenn man dazu keine lust hat kann man sich die Kommentare auch sparen.
-
...
-
So ich hab mal wieder was fertig, ok ich hab noch mehr fertig aber das hier wollte ich zeigen.
(Seit nicht zu böse mit mir!
) Das ganz soll mir die Huffman Codewörter bauen nach diesem Prinzip:
1. Symbole nach aufsteigender länge sotieren.
2. Erstes auf "0" setzen(alle Stellen).
3. Inkrementieren und nächstem Symbol zuweisen.
4. Nullen auffüllen bis zur nächsten Länge.
5. Wenn noch Codewörter da sind bei 3. fortfahren./* * function to save the hufftree codewords */ void Huffman::Codewords(const char* dhtpre){ int buff = -1; int dhtint; for(int i=5; i<21; ++i){ //for loop from 1-16 dhtint = (int)dhtpre[i]; //pointer of dht (casted in int) for(int j=0; j<dhtint; j++){ //for loop if dhtint is not 0 buff++; hftree.codeword = buff; hftree.length = (i-4); hf.push_back(hftree); //put the struct with codeword and the length in vector hf } if(buff > 0){ //shift buff binär for 1 to the left (fill it up with 0) buff = buff << 1; } } }FF C4 00 29 10 01 00 02 01 03 03 03 04 02 03 00 00 00 00 00 00Der Pointer dhtpre liegt immer auf dem FF. Es geht hier um die letzten 16 Zeichen, die die Längen für die Codewörter angeben.
-
Enno schrieb:
Meine Aufgabe ist es JPEG Bilder zu komprimieren.
Wenn du so etwas sagst, ist es doch kein Wunder, dass man dich fragt, warum du das komplett selbst programmieren willst. libjpeg hat 'ne freie Lizenz.
Enno schrieb:
Problem hab ich beim Anfang. Wie schaff ich es, wenn ich das Bild geladen hab (meinetwegen in einem Vektor oder in einem Filestream), das Bild in 8x8 Blöcke zu zerteilen und eine DCT durch zu führen? Das bereitet mir grade am meisten Schwierigkeiten.
Das ist kein C++ Problem. Es ist ein "Ich habe zu wenig Programmiererfahrung"-Problem, bei dem wir dir nicht wirklich helfen können. Guck dir einfach an, wie andere Leute es gemacht haben. Ich denke, es ist sehr lehrreich, sich mal guten fremden Code anzugucken, der ein JPEG-Bild dekodiert.
Vergiss nicht, dass man typischerweise bei JPEG in einem YUV-basierten Farbraum arbeitet und eine Farbunterabtastung durchführt. Das Chrominanzsignal wird meist in beiden Richtungen um Faktor 2 dezimiert, weswegen es auch zu 16x16 Pixel Macroblöcken kommt. Das sind 4 8x8 Blöcke für das Helligkeitssignal und ein 8x8 Block jeweils für eines der Farbdifferentiale.
Das mit dem Huffman geht auch viel eleganter. Es gibt da so einen schönen Algorithmus, der nennt sich "package merge". Er arbeitet nur auf einem int-Array rum und spuckt dir dann die Längen der Codewörter aus. Nix mit dynamisch allozierten Knoten eines Binärbaums. Das coole ist, dass man sogar eine maximale Codewordlänge vorgeben kann.
Enno schrieb:
[...] Und ja es ist ein schweres Thema und ich bin Anfänger aber ich kämpf mich da durch.
Dann musst du Dich wohl durchkämpfen. Aber erwarte nicht, dass da 'was "Ordentliches" bei rauskommt, wenn überhaupt. Du wirst sicherlich wegen der mangelnden Erfahrung so einige Entscheidungen treffen, die sich im Nachhinein als nachteilhaft herausstellen.
-
Hey krümelkacker!
Viel dank für dein Beitrag.
Vorweg erstmal soll gesagt sein das ich weiß das da einiges mist sein kann so wie ich es mache. Aber das ist schon ok.Zu den Farbräumen. Du meinst wahrscheinlich YCbCr ?? Dadran abreite ich grade. Also Unterabtastung und was dazu gehört. Danke für deine Tipps.