JPEG Bilder die 2te



  • SeppJ schrieb:

    Enno schrieb:

    getpointer ist vielleicht als Name falsch gewählt aber bis auf den schirtt den ich Zitiert habe verstehe ich dich nicht.
    1. Ich kann doch mein Speicher so verwalten ich hab ja auch mein delete drin.?

    Du darfst auch gerne zu Fuß über die Autobahn gehen, trotzdem ist es nicht unbedingt gut, so zu handeln.

    Ist doch aberm it new schneller?

    Unter anderem. Zudem viel einfacher zu benutzen. Dein Code enthält nämlich mindestens noch einen ⚠ dicken ⚠ Fehler bei der manuellen Speicherverwaltung, den jeder hier im Forum auf den ersten Blick sehen würde. Das wurde dir aber schon so oft gesagt, das sag ich dir nicht noch einmal, lies deine alten Threads.

    Du sprichst den const char* an richtig? Ich weiß nicht aber du weiß ja nicht was ich da zurück gebe. Ich gebe dort einen Pointer zurück der in einem struct liegt. Kp ob du das dann sinnvoller findest. Aber da ich jetzt mehr wissen hab als in meinen alten Threads darfst du gerne mir sagen wieso das ein DICKER Fehler ist.

    SeppJ schrieb:

    2. WTF?! Wie soll buildQT den jetzt wissen was abgeht und wo sie anfängt wenn du die getPointer Funktion einfach "wegkürzt"??

    Ich habe sie bloß nicht jedes Mal gezeigt. Deine Empörung zeigt aber, dass die Funktionen nicht unabhängig sind und meine Vermutung

    SeppJ schrieb:

    Ist das eigentlich richtig, dass die beiden Member unabhängig und frei aufrufbar sind? Das klingt doch stark danach, als sollten die beiden private sein und vom Konstruktor aufgerufen werden.

    wohl voll ins Schwarze trifft. Lass mich raten wie das Objekt benutzt wird:

    DQT dqt;
    dqt.getPointer();
    dqt.buildQT(parameter1, parameter2);
    

    Trifft es das so etwa? Und wenn man den zweiten Schritt weglässt, dann klappt der dritte nicht und nur mit dem Ergebnis des ersten Schritts kann man wahrscheinlich auch noch nichts machen.

    Nope so wird das nicht benutzt.

    Ich hab jetzt den ganzen kram noch einmal verbessert.

    DQT.h

    #include <iostream>
    
    #include "marker.h"
    
    class DQT{
    public:
      ZigZag();
      ~ZigZag();
    private:
      void findDQT();
      void buildQT(int dqtcount);
      Marker *marker;
      int    quantTable[0][64];
    };
    

    DQT.cpp

    #include <iostream>
    #include <vector>
    
    #include "DQT.h"
    
    DQT::DQT(){
      marker = new Marker();
    }
    
    DQT::~DQT(){
      delete marker;
    }
    
    /*
     * function to build quantisation table
     */
    void DQT::buildQT(){
      const char* dqt = marker->getDQT();
      do{
        bool up = true;
        int count = 0;
        for(int i=0; i<8; i++){
          if(up){
            for(int j=0; j<=i; j++){
              quantTable[i][count++] = (char)dqt[8 * (i - j) + j];
            }   
          }else{
            for(int j=i; j>=0; j--){  
              quantTable[i][count++] = (char)dqt[8 * (i - j) + j];
            }
          }
          up = !up;
        }
        for(int i=7; i>=0; i--){
          if(up){
            for(int j=0; j<i; j++){
              quantTable[i][count++] = (char)dqt[8 * (7 - j) +  8 - i + j];
            }
          }else{
            for(int j=0; j<i; j++){
              quantTable[i][count++] = (char)dqt[8 * (8 - i + j) + 7 - j];
            }
          }
          up=!up;
        } 
      }while(marker->nextIndex() == true)
    }
    

    nur kleiner ausschnitt aus maker.h und marker.cpp
    maker.h

    struct POS{ //save pointers on Markers
      char *APP;
      char **DQT; //to save same pointers in 1 with index [DQTcount]
      char *SOF;
      char **DHT; //to save same pointers in 1 with index [DHTcount]
      char *SOS;
      int  DQTcount; 
      int  DHTcount;
    };
    

    marker.cpp

    void Marker::findMarker(const char* SOI, size_t length){
      for(unsigned int i=0; i<length; i++){
        if(SOI[i] == (char)0xff){
          i++;
          switch(SOI[i]){
            case 0xe0:
              POS.APP = &SOI[i];
              break;
            case 0xdb:
              POS.DQT[POS.DQTcount] = &SOI[i];
              POS.DQTcount++;
              break;
            case 0xc0:
              POS.SOF = &SOI[i];
              break;
            case 0xc4:
              POS.DHT[POS.DHTcount] = &SOI[i];
              POS.DHTcount++;
              break;
            case 0xda:
              POS.SOS = &SOI[i];
              break;    
          }//switch
        }//if
      }//for
    }
    
    /*
     * next function to return all DQT pointer
     */
    bool Marker::nextIndex(){
      DQTindex++;
      if(POS.DQT[DQTindex] > POS.DQT[POS.DQTcount]) return false;
      return true;
    }
    const char* Marker::getDQT(){
      return POS->DQT[POS.DQTcount];
    }
    

    Das mit dem int quantTable[0][64] mach ich jetzt also muss dazu nicht unbedingt was gesagt werden. Das ändere ich jetzt wollte nur schon mal auf SeppJ antworten.



  • 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 ein char ist? Ohnehin solltest du keine C-Casts, sondern static_cast und 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[] und delete[] 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 == true sind unnötig.
    • Statt if (x) return true; else return false; schreibe return 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.


  • 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 nach char , was schon ein char ist? Ohnehin solltest du keine C-Casts, sondern static_cast und 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 statt new[] und delete[] 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 == true sind unnötig.
    **
    Warum?

    [*]Statt if (x) return true; else return false; schreibe return x; .
    ich weiß nicht aber für mich leuchtet das nicht ein warum ich da return x; machen soll. Ich will ja nicht x haben sondern solange true zurück geben bis **DQT also *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 == true sind 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; schreibe return x; .
    ich weiß nicht aber für mich leuchtet das nicht ein warum ich da return x; machen soll. Ich will ja nicht x haben sondern solange true zurück geben bis **DQT also *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 == true sind unnötig.
    **Warum?

    Du schreibst auch nicht if ((2 < 3) == true) , wieso also if (marker->nextIndex() == true) ? Davon abgesehen ist "nextIndex" ein verwirrender Name, niemand würde hier einen bool -Typen erwarten.

    Enno schrieb:

    Ich will ja nicht x haben sondern solange true zurück geben bis **DQT also *DQT[] komplett durch ist.

    Nimm nicht alles wörtlich, x war 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 == true sind unnötig.
    **Warum?

    Du schreibst auch nicht if ((2 < 3) == true) , wieso also if (marker->nextIndex() == true) ? Davon abgesehen ist "nextIndex" ein verwirrender Name, niemand würde hier einen bool -Typen erwarten.

    Ok das leuchtet ein. Danke.

    Nexus schrieb:

    Enno schrieb:

    Ich will ja nicht x haben sondern solange true zurück geben bis **DQT also *DQT[] komplett durch ist.

    Nimm nicht alles wörtlich, x war 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 ++i statt i++ schreiben, es ist nicht mehr Schreibaufwand. Der Code mit den 3 Zeilen sollte nur die Semantik von i++ 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 ++i statt i++ schreiben, es ist nicht mehr Schreibaufwand. Der Code mit den 3 Zeilen sollte nur die Semantik von i++ 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. 😉


  • Mod

    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 00
    

    Der 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.


Anmelden zum Antworten