Kompressor/Dekompressor input_code / output_code



  • Hi!

    ich schreibe ein Programm mit einem Wechselpuffer welches über ein Wörterbuch (4 bytes / wort) effizient mit Hashalgorithmus komprimieren und dekomprimieren soll. Leider funktioniert meine Inputfunktion nicht richtig für das Expandieren in die usrspr. Textdatei. 😡 Ich habe versucht, eine Funktion vom lzw zu benutzen und die 4 Bytes auf 2 BITS zu codieren. Er schreibt zwar raus und das Komprimat ist 70 % weniger. Aber zurück geht es nicht. LZW funktioniert nur mit 12 bzw. 13 BITS. Ich wäre für jeden Hinweis für solch eine Funktion zum Schreiben des Outputs und anschließenden Expandieren dankbar.

    Gruß

    kjesse



  • Wie sieht das im Klartext aus?
    (übrigens: Eine Komprimierung von 4 Byte (=32 Bit) auf 2 Bit ist schon recht gut)



  • Der Input/Output sieht wie folgt aus. BITS ist 2 bei mir. Anscheinend funktioniert es nur mit BITS = 12. Ich weiß nicht was ich ändern muss für BITS = 2.

    unsigned int input_code(FILE *input)
    {
    unsigned int return_value;
    static int input_bit_count=0;
    static unsigned long input_bit_buffer=0L;

    while (input_bit_count <= 24)
    {
    input_bit_buffer |=
    (unsigned long) getc(input) << (24-input_bit_count);
    input_bit_count += 8;
    }
    return_value=input_bit_buffer >> (32-BITS);
    input_bit_buffer <<= BITS;
    input_bit_count -= BITS;
    return(return_value);
    }

    void output_code(FILE *output,unsigned int code)
    {
    static int output_bit_count=0;
    static unsigned long output_bit_buffer=0L;

    output_bit_buffer |= (unsigned long) code << (32-BITS-output_bit_count);
    output_bit_count += BITS;
    while (output_bit_count >= 😎
    {
    putc(output_bit_buffer >> 24,output);
    output_bit_buffer <<= 8;
    output_bit_count -= 8;
    }
    }



  • Ich fürchte, du hast das Prinzip der (verlustfreien) Kompression nicht verstanden. Woher hast du denn dieses Verfahren ausgegraben?
    Ich bin mir zwar nicht ganz sicher, wie der Code dort funktionieren soll, aber wie es aussieht, überlagert er per ODER die einzelnen Eingabezeichen in einen großen Block, aus dem er dann zwei Bit herausschneidet.

    (und mit dem Lempel-Zip-Welch-Algorithmus scheint das aus wenig zu tun zu haben)



  • Ich habe die Funktionen von einem Programm lzw.c (Mark Nelson). Ich schreibe meinen ersten Kompressor und möchte unabhängig von lzw ein 4 Byte Wort "bitaufbereitet" in mein Outputfile schreiben. Leider kenne ich mich mit den Bitoperationen nicht aus. Der Kompressor soll nicht wie der LZW funktionieren. Ich habe die Funktionen von lzw.c nur als Bsp. genommen.



  • Bevor du sowas machst, solltest du dir erstmal überlegen, was du eigentlich beabsichtigst. Um 4 Byte "bitaufbereitet" (was immer das bedeuten mag) zu übertragen, gibt es viele Möglichkeiten - nur dürften aus den wenigsten davon wieder die Original-Eingabe rekonstruierbar sein.
    Wenn du wirklich etwas komprimieren willst, mußt du etwas mehr Aufwand betreiben als die Eingabe-Bits willkürlich miteinander zu kombinieren. Das geht nur, wenn du die Struktur der Eingabe analysierst und dich daran anpasst.
    (darum baut LZW auch ein Wörterbuch auf, um den Text zu komprimieren, andere Verfahren ermitteln vor der Umwandlung die Häufigkeit der einzelnen Zeichen (Huffman) oder wenden Transformationen auf die Daten an, die eine leichter komprimierbare Struktur ergeben (JPEG))



  • Ich habe angefangen mir ein 64K Dictionary zu bauen, welches 4 Bytes eines Gleitfensters haben soll. Ich suche über einen Hashcode darin, ob der Code schon einmal vorkam. Bei einem Treffer wollte ich das Wort "codiert" in den Output schreiben, bei einem Nicht-Treffer nur das erste Byte schreiben und das Wort c1c2c3c4 von ...v3v2v1c1c2c3c4... abspeichern im Dictionary. v1 ist Vorläufer und c1 der Suffix. Ich habe keine Ahnung wie man aus dem Dictionary "codiert" schreibt, damit man einen Kompressionseffekt hat.


Anmelden zum Antworten