LZW Komprimierung - 10 signifikante Bits in eine Binärdatei schreiben.



  • Hallo allerseits,

    ich muss die einzelnen Codes, die ich durch eine LZW-Komprimierung erhalte, in eine Binärdatei schreiben.

    Der Aufgabe nach sollen die 10 signifikanten Bit in die Datei geschrieben werden. Der Code liegt derzeit als Int vor.

    Wir wurden in der Uni in C++ sozusagen ins kalte Wasser geworfen und ich weiß an diesem Punkt einfach nicht weiter, was zu machen ist, bzw. wie es zu verstehen ist.

    Was mache ich denn mit einem Int (bspw. 101), um die 10 signifikanten Bit in die Binärdatei zu schreiben?

    Bin gar nicht auf fertige Lösung aus, Denkanstöße und Tipps wären toll.

    Danke Euch vorab.



  • Da man keine einzelnen Bits, sondern nur Zeichen schreiben kann, musst du deinen Strom von 10-Bit-Worten in 8-Bit-Häppchen zerteilen:

    z.B.:
    012345678901234567890123456789012345678901234567890123456789.....
    012345670123456701234567012345670123456701234567012345670123.....

    Beim Schreiben des ersten 10-Bit-Wortes kannst du also nur 8 Bit schreiben und musst die anderen 2 Bit puffern. Wenn das nächste 10-Bit-Wort ankommt, kannst du davon 6 Bit nehmen und mit dem Puffer zusammen wieder ein Zeichen voll machen, der Puffer enthält nun 4 Bit. Und so weiter.

    Du musst entscheiden (das ist möglicherweise durch das Dateiformat vorgegeben), welche Bits du von den 10 Bit zuerst wegschreibst, die oberen oder die unteren.



  • Bashar hat es schon beschrieben wie es geht. IMHO ist es aber auch für jemanden, der C++ kann, die Umsetzung dessen vielleicht gar nicht so trivial, wie es am Anfang scheint.
    Ich habe mich mal dran versucht:

    void save10as8( std::ostream& out, int* src, unsigned size )
    {
        int* const srcEnd = src + size;
        int bits = 10;  // 'bits' gibt an, wie viele Bits zu schreiben sind
        while( src != srcEnd )
        {
            char byte;  // 1 Byte := 8Bit
            if( bits < 8 )
            {
                byte = (*src << (8 - bits)) & 0xFF;
                bits += 2;
                if( ++src != srcEnd )
                {
                    byte |= (*src >> bits) & 0xFF;
                }
            }
            else
            {
                bits -= 8;
                byte = (*src >> bits) & 0xFF;
                if( bits == 0 )
                {
                    ++src;
                    bits = 10;
                }
            }
            out.write( &byte, 1 ); // 8Bit schreiben
        }
    }
    

    dieser Code schreibt 'size' 10Bit-Integer 8Bit-weise weg. Beginnend mit den höher wertigen Bits. Aufgerufen wird er z.B. so:

    #include <iostream>
    #include <fstream>
    
    int main()
    {
        using namespace std;
        int data[] = { 0x3ff, 0x000, 0x155, 0x2AA }; // 10Bit-Integer hier nur zur Demo
        ofstream file( "comprim.dat", ios_base::binary );
        save10as8( file, data, sizeof(data)/sizeof(*data) );
        return 0;
    }
    

    Fischi2k schrieb:

    Was mache ich denn mit einem Int (bspw. 101), ...

    bin mir gar nicht so sicher, ob Du die Erklärung von SeppJ in Deinem anderen Thread verstanden hast 😕
    Nur zur Klarstellung, jeder Int-Wert oben sollte im Intervall von [0..1023] bzw. [0x0..0x3FF] bzw. [0%0..0%1111111111] liegen, was ohne jede Konvertierung immer das gleiche ist!

    Gruß
    Werner


Log in to reply