Bytes zu 12 Bits und anders herum. (Fehlerhafter LZW Source)
Es geht mir eigentlich darum eine komprimierung zu haben, welche ich abändern kann nach belieben... eventuell verbessern kann und halt einiges mit ihr Probieren kann, sozusagen unter anderem als Lern zweck. Daher funktioniert keine fertige Lib oder DLL 
Möchte halt später eine komprimierung in mein Packformat stecken, und da würde ich halt gerne nach und nach verschiedene komprimier Methoden einbauen... halt auch welche die man selbst eventuell verbessert hat. Hab bis jetzt halt nur damals eine verlustfreie komprimierung für Bilder geschrieben(Bei bildern ist das relativ leicht, weil es da ja viele Pixel mit der gleichen Farbe gibt)... Die war ganz Okay, aber halt nicht so gut wie PNG. Nur leider ist mir das bei meinem großen Platten Crash alles verloren gegangen. ^^

Möchte halt später eine komprimierung in mein Packformat stecken, und da würde ich halt gerne nach und nach verschiedene komprimier Methoden einbauen... halt auch welche die man selbst eventuell verbessert hat. Hab bis jetzt halt nur damals eine verlustfreie komprimierung für Bilder geschrieben(Bei bildern ist das relativ leicht, weil es da ja viele Pixel mit der gleichen Farbe gibt)... Die war ganz Okay, aber halt nicht so gut wie PNG. Nur leider ist mir das bei meinem großen Platten Crash alles verloren gegangen. ^^
- NicknameFJ
- Beiträge: 324
- Registriert: 03.06.2007 14:36
- Wohnort: Von der Sonne aus gesehen der dritte Planet
Ich steige zwar bei dem Algo nicht durch, habe mich nicht mit LZW Kompr. beschäftigt, aber was den Speed angeht überdenke mal dies:
Innerhalb der Schleife 256 to 4095 kann doch jeder Eintrag nur einmal vorkommen oder ? Wenn Du den Eintrag dann endweder gefunden oder ergänzt hast musst Du die Schleife doch nicht bis zum Ende durchgehen und weitersuchen ?
Wenn meine obige Annahme richtig ist benutze mal BREAK und Du wirst sehen, ohne weitere Optimierungen die man noch durchführen kann wird das Prg. DEUTLICH schneller.
Ähm ja fällt mir noch gerade beim Drüberschauen auf
Die Schleife läuft von 256 bis 4095
Wenn an Position 256 im Wörterbuch der Eintrag nicht vorkommt erstellt Du schon einen neuen Eintrag im Wörterbuch, da dann ja der ELSE-Zweig ausgeführt wird. Dürftest Du aber den neuen Eintrag nicht erst dann erstellen, wenn Du aller bisherigen Einträge geprüft hast ob der gewünschte vorkommt und erst wenn der Eintrag noch überhaupt nicht in der Tab. vorkommt (Schleifendurchläufe 256 bis 4095 komplett durchgeprüft) einen neuen erstellen ?
Innerhalb der Schleife 256 to 4095 kann doch jeder Eintrag nur einmal vorkommen oder ? Wenn Du den Eintrag dann endweder gefunden oder ergänzt hast musst Du die Schleife doch nicht bis zum Ende durchgehen und weitersuchen ?
Wenn meine obige Annahme richtig ist benutze mal BREAK und Du wirst sehen, ohne weitere Optimierungen die man noch durchführen kann wird das Prg. DEUTLICH schneller.
Ähm ja fällt mir noch gerade beim Drüberschauen auf
Die Schleife läuft von 256 bis 4095
Wenn an Position 256 im Wörterbuch der Eintrag nicht vorkommt erstellt Du schon einen neuen Eintrag im Wörterbuch, da dann ja der ELSE-Zweig ausgeführt wird. Dürftest Du aber den neuen Eintrag nicht erst dann erstellen, wenn Du aller bisherigen Einträge geprüft hast ob der gewünschte vorkommt und erst wenn der Eintrag noch überhaupt nicht in der Tab. vorkommt (Schleifendurchläufe 256 bis 4095 komplett durchgeprüft) einen neuen erstellen ?
PS: Alle im Text enthaltenen Schreibfehler sind beabsichtigt und dienen der Belustigung aller


Also habs gerade geändert und probiert ^^ Wau... erstaunlich... also jetzt hat er die Datei die ich Gestern gepackt habe, welche dannach fast 500kb war, besser gepackt... Also von 328kb auf 318kb ^^ nicht viel aber gepackt... Ob das auch wieder problemlos entpacken geht ist jetzt die andere Frage...
Nur die Geschwindigkeit ist immer noch mies... und für so eine schlechte komprimierung geht wohl keiner so eine Zeit ein.
mfg.
FlowPX2
Nur die Geschwindigkeit ist immer noch mies... und für so eine schlechte komprimierung geht wohl keiner so eine Zeit ein.
Code: Alles auswählen
#SourceFile=0
#EndFile=1
Procedure.s Compress(FromFile.s,ToFile.s)
;Dateien öffnen
OpenFile(#SourceFile,FromFile.s)
OpenFile(#EndFile,ToFile.s)
;Wörter Buch
Dim WordBook.s(4096)
For i = 0 To 255
WordBook.s(i) = Str(i)
Next
;Byte und Word Variablen
Global Wert1.w = 0
Global Wert2.w = 0
Global Byte1.b = 0
Global Byte2.b = 0
Global Byte3.b = 0
Global Result.l = 0
WordBookIndex = 256
WordBookExist = 0
;Zu komprimierende Datei laden
SourceFileSize = FileSize(FromFile.s)+1
Dim SourceBytes(SourceFileSize)
Repeat
LoadCurPos.l = Loc(#SourceFile)
SourceBytes(LoadCurPos.l) = ReadByte(#SourceFile)&$FF
Until Eof(#SourceFile)
CurPos.l = 0
Repeat
WriteInFile = WriteInFile + 1
ByteA = SourceBytes(CurPos.l)
ByteB = SourceBytes(CurPos.l+1)
Wert1.w = ByteA
Wert2.w = ByteB
;Prüfe ob in Wörterbuch schon vorhanden
WordBookExist = 0
For i = 256 To 4095
If WordBook.s(i) = Str(ByteA)+Str(ByteB)
WordBookExist = 1
Break
EndIf
Next
If WordBookExist = 1
;Wenn im Wörterbuch vorhanden
If WriteInFile = 1
Wert1.w = i
Else
Wert2.w = i
EndIf
CurPos.l = CurPos.l + 1 ;Wenn im Wörterbuch vorhanden, dann nächstes Byte nicht nochmal verarbeiten
Else
;Wenn nicht im Wörterbuch vorhanden
If WordBookIndex < 4096
WordBook(WordBookIndex) = Str(ByteA)+Str(ByteB)
WordBookIndex = WordBookIndex + 1
EndIf
If WriteInFile = 1
Wert1.w = ByteA
Else
Wert2.w = ByteA
EndIf
EndIf
;Schreibe in Datei wenn genug Bits da sind um 3Bytes zu füllen
If WriteInFile = 2
!movzx eax,[v_Wert1]
!mov dx,[v_Wert2]
!shl edx,12
!or eax,edx
!mov [v_Result],eax
!mov [v_Byte2],ah
!mov [v_Byte3],al
!shr eax,8
!mov [v_Byte1],ah
;Schreibe kompremierte version in Datei
WriteByte(#EndFile,Byte1.b&$FF);
WriteByte(#EndFile,Byte2.b&$FF);
WriteByte(#EndFile,Byte3.b&$FF);
WriteInFile = 0
EndIf
CurPos.l = CurPos.l + 1
Until CurPos = SourceFileSize
ProcedureReturn RetVal.s
EndProcedure
Compress("C:\Program Files\Zak2\SDL.dll","C:\Program Files\Zak2\SDL2.lzw")
FlowPX2
Hab mir gerade eine LZW version in C++ geladen, die läuft ja genau so langsam! Das kann man ja niemanden zumuten... daher wird das wohl nicht so oft bei großen Dateien eingesetzt.
Das einzigste, Sie hat eine bessere Kompression.. aber ich weiß schon wo da der fehler liegen könnte.
Was mich jetzt nur wundert... Wie packt es... WinZip, WinRar und die ganzen andere Formate so schnell zu sein!?!?
mfg.
FlowPX2
Das einzigste, Sie hat eine bessere Kompression.. aber ich weiß schon wo da der fehler liegen könnte.
Was mich jetzt nur wundert... Wie packt es... WinZip, WinRar und die ganzen andere Formate so schnell zu sein!?!?
mfg.
FlowPX2
Habe gerade auch etwas gecodet und sehe jetzt, es gibt was Neues von FlowPX2. Habe seins eben getestet und ich sage mal, es stimmt nicht. Ich habe mit dem Beispiel "LZWLZ78LZ77LZCLZMWLZAP" getestet (aus dem Internet mit Erläuterungen). Teste mal die Ausgabe (meine 2 Debugs). Hier erstmal mein Code:
Bei diesem kurzen Beispiel ist die Ausgabe-Datei (fast natürlich) länger als die Original-Datei; das ist kein Fehler! Mein Schachprogramm wurde von 82 auf 70 Kb "komprimiert". Viel bessere Ergebnisse erzielt man mit längeren möglichen Wörterbuch-Einträgen (hier ja nur 2 Zeichen).
Gruß
Helle
Code: Alles auswählen
#SourceFile=0
#EndFile=1
Procedure.s Compress(FromFile.s,ToFile.s)
;Dateien öffnen
OpenFile(#SourceFile,FromFile.s)
OpenFile(#EndFile,ToFile.s)
;Wörter Buch
Dim WordBook.s(4096)
For i = 0 To 255
WordBook.s(i) = Str(i)
Next
;Byte und Word Variablen
Global Wert1.w = 0
Global Wert2.w = 0
Global Byte1.b = 0
Global Byte2.b = 0
Global Byte3.b = 0
ByteA.b = 0
ByteB.b = 0
;Global Result.l = 0
WordBookIndex.l = 256
;Zu komprimierende Datei laden
SourceFileSize = FileSize(FromFile.s)+1
Dim SourceBytes.b(SourceFileSize)
Repeat
LoadCurPos.l = Loc(#SourceFile)
SourceBytes(LoadCurPos.l) = ReadByte(#SourceFile)&$FF
Until Eof(#SourceFile)
CurPos.l = 0
Repeat
WriteInFile + 1
ByteA = SourceBytes(CurPos)
ByteB = SourceBytes(CurPos+1)
;Wert1.w = ByteA
;Wert2.w = ByteB
;Prüfe ob in Wörterbuch schon vorhanden
For i = 256 To WordBookIndex ;4095
If WordBook.s(i) = Str(ByteA)+Str(ByteB)
;Wenn im Wörterbuch vorhanden
If WriteInFile = 1
Wert1 = i
Else
Wert2 = i
EndIf
CurPos + 1 ;Wenn im Wörterbuch vorhanden, dann nächstes Byte nicht nochmal verarbeiten
ISW = 1 ;Merker: ist Wörterbuch
;Else
EndIf
Next
If ISW = 0
;Wenn nicht im Wörterbuch vorhanden
If WordBookIndex < 4096
WordBook(WordBookIndex) = Str(ByteA)+Str(ByteB)
WordBookIndex + 1
EndIf
If WriteInFile = 1
Wert1 = ByteA & $FF
Else
Wert2 = ByteA & $FF
EndIf
EndIf
; Next
;Schreibe in Datei wenn genug Bits da sind um 3 Bytes zu füllen
If WriteInFile = 2
;Debug "Wert1 schreiben = " + Str(Wert1)
;Debug "Wert2 schreiben = " + Str(Wert2)
!movzx eax,[v_Wert1]
!movzx edx,[v_Wert2]
!shl edx,12
!or eax,edx
;!mov [v_Result],eax
!mov [v_Byte2],ah ;2
!mov [v_Byte1],al ;3 geändert!
!shr eax,8
!mov [v_Byte3],ah ;1
;Schreibe komprimierte Version in Datei
WriteByte(#EndFile, Byte1 & $FF)
WriteByte(#EndFile, Byte2 & $FF)
WriteByte(#EndFile, Byte3 & $FF)
WriteInFile = 0
EndIf
ISW = 0
CurPos + 1
Until CurPos = SourceFileSize
CloseFile(#SourceFile)
CloseFile(#EndFile)
;ProcedureReturn RetVal.s
EndProcedure
Compress("C:\Temp\T.exe", "C:\Temp\T.lzw") ;sind meine Werte!
End
Gruß
Helle