Bytes zu 12 Bits und anders herum. (Fehlerhafter LZW Source)

Für allgemeine Fragen zur Programmierung mit PureBasic.
Benutzeravatar
NicknameFJ
Beiträge: 324
Registriert: 03.06.2007 14:36
Wohnort: Von der Sonne aus gesehen der dritte Planet

Beitrag von NicknameFJ »

@FlowPX2

Wenn es bei Dir mit .c nicht klappt kann es eigentlich nur daran liegen, dass Du das Prg. im Unicode Modus kompiliert hast.

.c ist eigentlich kein Datentyp für Byte sondern für Character und der hat in Unicode eben nicht 1 sondern 2 Byte

Grüße

Joachim
PS: Alle im Text enthaltenen Schreibfehler sind beabsichtigt und dienen der Belustigung aller

Bild
FlowPX2
Beiträge: 42
Registriert: 05.05.2008 14:08

Beitrag von FlowPX2 »

Ahh interessant.. Danke.. Da sieht man Unicode hat nicht nur vorteile *hehe*
Naja ich Quäle mich gerade jetzt damit ab das ganze jetzt auch rückwärts zum laufen zu bringen also... wenn ich 3 Bytes habe das ich 2 Word heraus bekomme... Werd mal herum probieren, das kann doch nicht so schwer sein ;-)

mfg.
FlowPX2
Benutzeravatar
NicknameFJ
Beiträge: 324
Registriert: 03.06.2007 14:36
Wohnort: Von der Sonne aus gesehen der dritte Planet

Beitrag von NicknameFJ »

Ähm - übrigens

Willkommen hier im Forum, habe erst jetzt Dein Anmeldedatum gesehen
PS: Alle im Text enthaltenen Schreibfehler sind beabsichtigt und dienen der Belustigung aller

Bild
FlowPX2
Beiträge: 42
Registriert: 05.05.2008 14:08

Beitrag von FlowPX2 »

Ja danke ^^ Aber mit PureBasic programmiert hab ich damals schon nur mich nie im Forum angemeldet, da die Dokumentationen die es für PureBasic gibt recht gut geschrieben sind.

Naja und jetzt versuch ich halt seit ein paar Tagen wieder was in PB zu coden, weil ich nen kleines PackFormat machen möchte mit einigen neuen Funktionen die es noch nicht gibt... halt nur nich soo eine gute kompremierung... Daher versuch ich mich gerade mal daran den LZW-Algo in PureBasic zu coden.

mfg.
FlowPX2
FlowPX2
Beiträge: 42
Registriert: 05.05.2008 14:08

Beitrag von FlowPX2 »

Erste probleme Geschaft ^^ Natürlich gleich mal hier ins Forum posten, weil vll. brauch es später mal jemand.

Also mit dem Code kann man 2Words zu 3Bytes umwandeln oder 3Bytes wieder zu 2Words ^^

Code: Alles auswählen


;2Word welche zu 3Bytes umgewandelt werden sollen
Wert1.w = %100001110000    ;irgendwelche 12 Bits
Wert2.w = %011000000111

Byte1.b = 0
Byte2.b = 0
Byte3.b = 0
Result.l = 0

!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

Debug "Von Word to Byte"
Debug "Komplett  :  "+RSet(Bin(Result), 24, "0")
Debug "Byte 1:  "+RSet(Bin(Byte1&$FF), 8, "0")
Debug "Byte 2:  "+RSet(Bin(Byte2&$FF), 8, "0")
Debug "Byte 3:  "+RSet(Bin(Byte3&$FF), 8, "0")
Debug "Word1  :  "+RSet(Bin(Wert1), 12, "0")
Debug "Word2  :  "+RSet(Bin(Wert2), 12, "0")
Debug ""
Debug ""

;3Bytes welche zu 2Word umgewandelt werden sollen
;Byte1.b = 255
;Byte2.b = 0
;Byte3.b = 255

!mov ah,[v_Byte1]
!shl eax,8
!mov ah,[v_Byte2]
!mov al,[v_Byte3]
!mov edx,eax
!mov [v_Result],eax
!shr edx,12
!mov [v_Wert2],dx
!shl edx,12
!xor eax,edx
!mov [v_Wert1],ax

Debug "Von Byte to Word"
Debug "Komplett  :  "+RSet(Bin(Result), 24, "0")
Debug "Byte 1:  "+RSet(Bin(Byte1&$FF), 8, "0")
Debug "Byte 2:  "+RSet(Bin(Byte2&$FF), 8, "0")
Debug "Byte 3:  "+RSet(Bin(Byte3&$FF), 8, "0")
Debug "Word1  :  "+RSet(Bin(Wert1), 12, "0")
Debug "Word2  :  "+RSet(Bin(Wert2), 12, "0")
Viel Spaß mit dem herum spielen, falls jemand es brauch... Und jetzt probier ich mal darauf die Komprimierung aufzubauen ^^ Ohje.

mfg.
FlowPX2
Benutzeravatar
NicknameFJ
Beiträge: 324
Registriert: 03.06.2007 14:36
Wohnort: Von der Sonne aus gesehen der dritte Planet

Beitrag von NicknameFJ »

Also Dein Code gibt bei mir folgenden Output

Von Word to Byte
Komplett : 100000001100000011110000
Byte 1: 01100000
Byte 2: 01111000
Byte 3: 01110000
Word1 : 100001110000
Word2 : 011000000111


Von Byte to Word
Komplett : 111111010110000001111000
Byte 1: 01100000
Byte 2: 01111000
Byte 3: 01110000
Word1 : 100001110000
Word2 : 111111111111


Wenn ich mir hier das Ergebnis von Byte nach Word ansehe - hier WORD2 - da sind aber viele Einsen :shock:

Habe jetzt nur keine Lust mehr - *müde er ist* - mir Deinen Code anzusehen, aber so auf die schnelle, da hackt noch was

Nur mal so zum Verständnis:
In Deinem ersten Posting hast Du geschrieben, dass Du zwei ByteWerte (=zusammen 16 Bit) zu 24 Bit expandieren willst. Danach war immer die Rede davon, zwei 12 Bit-Werte zu 24 Bit aneinander zu reihen - was ist den wirklich gewünscht ???
PS: Alle im Text enthaltenen Schreibfehler sind beabsichtigt und dienen der Belustigung aller

Bild
FlowPX2
Beiträge: 42
Registriert: 05.05.2008 14:08

Beitrag von FlowPX2 »

Gewünscht ist Folgendes:

1. Lese ich aus einer Datei 2 Bytes heraus... also 16bit
2. Prüfe ich ob diese reihenfolge im Wörterbuch steht.
3. Wenn ja dann werden die 2 Bytes also 16bit durch 2 Zahlen ersetzt welche ins gesammt 24bit brauchen also 3bytes. Also 2 Zahlen die von 0 bis 4095 gehen und daher 12bits brauchen ^^

Also die zahlen 12, 16 und 24 bits sind gefallen ^^ und auch alle davon benötige ich leider ;)

komisch das Problem das du hast das alles voll mit 1 ist bei Word2 tritt bei mir wiederrum nicht auf... mal schauen vll. find ich ein fehler.

mfg.
FlowPX2
FlowPX2
Beiträge: 42
Registriert: 05.05.2008 14:08

Beitrag von FlowPX2 »

Hilfe!!! Was hab ich getan xDD

Also erstmal dachte ich es funktioniert... Weil eine Datei die 15kb hatte nur noch 12kb groß war. Doch dann hab ich eine Datei probiert die 328kb war... dannach war Sie 486kb groß! Dann hab ich Sie mir mal im Hex Editor angeschaut und bin mir jetzt sicher das es irgendwie total falsch läuft.

Hier das Skript... Es sollte eine Datei mit dem LZW Algo Komprimieren...
Aber es läuft der maßen lahm... also beim testen keine Files größer als 30kb nutzen.

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

;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
    For i = 256 To 4095
      If WordBook.s(i) = Str(ByteA)+Str(ByteB)
      
        ;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
    Next
    
    ;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\SDL.lzw") 
Eventuell kennt jemand sich ja genauer mit LZW aus und/oder weiß was hier aber sowas von falsch funktioniert.

mfg.
FlowPX2
Benutzeravatar
Helle
Beiträge: 566
Registriert: 11.11.2004 16:13
Wohnort: Magdeburg

Beitrag von Helle »

Eben beim Frühstück nur mal kurz draufgeschaut: Du musst unbedingt

Code: Alles auswählen

!movzx edx,[v_Wert2]
 
verwenden, sonst sind die oberen 4 Bits von EDX unbestimmt. Gilt hier für Result, was aber im Code nicht weiterverwendet wird (Kontrollzwecke?).

Gruß
Helle
Benutzeravatar
Helle
Beiträge: 566
Registriert: 11.11.2004 16:13
Wohnort: Magdeburg

Beitrag von Helle »

So müsste auch der andere Code funktionieren:

Code: Alles auswählen

;2Word welche zu 3Bytes umgewandelt werden sollen 
Wert1.w = %100001110000    ;irgendwelche 12 Bits 
Wert2.w = %011000000111 

Byte1.b = 0 
Byte2.b = 0 
Byte3.b = 0 
Result.l = 0 

!movzx eax,[v_Wert1] 
!movzx edx,[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 

Debug "Von Word to Byte" 
Debug "Komplett  :  "+RSet(Bin(Result), 24, "0") 
Debug "Byte 1:  "+RSet(Bin(Byte1&$FF), 8, "0") 
Debug "Byte 2:  "+RSet(Bin(Byte2&$FF), 8, "0") 
Debug "Byte 3:  "+RSet(Bin(Byte3&$FF), 8, "0") 
Debug "Word1  :  "+RSet(Bin(Wert1), 12, "0") 
Debug "Word2  :  "+RSet(Bin(Wert2), 12, "0") 
Debug "" 
Debug "" 

;3Bytes welche zu 2Word umgewandelt werden sollen 
;Byte1.b = 255 
;Byte2.b = 0 
;Byte3.b = 255 

!movzx eax,[v_Byte1] 
!shl eax,16 
!mov ah,[v_Byte2] 
!mov al,[v_Byte3] 
!mov edx,eax 
!mov [v_Result],eax 
!shr edx,12 
!mov [v_Wert2],dx 
!shl edx,12 
!xor eax,edx 
!mov [v_Wert1],ax 

Debug "Von Byte to Word" 
Debug "Komplett  :  "+RSet(Bin(Result), 24, "0") 
Debug "Byte 1:  "+RSet(Bin(Byte1&$FF), 8, "0") 
Debug "Byte 2:  "+RSet(Bin(Byte2&$FF), 8, "0") 
Debug "Byte 3:  "+RSet(Bin(Byte3&$FF), 8, "0") 
Debug "Word1  :  "+RSet(Bin(Wert1), 12, "0") 
Debug "Word2  :  "+RSet(Bin(Wert2), 12, "0") 
Gruß
Helle
Antworten