[VB.net][SNIPPET] LZ77 Dekompression.

    • [VB.net][SNIPPET] LZ77 Dekompression.

      Hallo,
      ich veröffentliche hier aus meinem Trainer Backsprite Editor Rebirth den LZ77 Dekomprimierungscode.
      Ich habe ihn mal für euch angepasst, hoffe, dass er so funktioniert.

      Quellcode

      1. Public Class LZ77
      2. Public Function Decompress(ByVal s As Stream, Optional ByVal offset As Integer = 0) As Byte()
      3. Dim lzSize As Integer
      4. Dim DataLeft As Integer
      5. Dim dcb As Byte
      6. Dim j As Integer
      7. Dim br As BinaryReader = New BinaryReader(s)
      8. br.BaseStream.Position = offset
      9. lzSize = br.ReadInt32()
      10. lzSize >>= 8
      11. DataLeft = lzSize
      12. Dim Destination(lzSize) As Byte
      13. On Error Resume Next
      14. While Not DataLeft <= 0
      15. ' Read Decode Byte
      16. dcb = br.ReadByte
      17. For i = 1 To 8
      18. Dim x As Byte = CByte((128 / (2 ^ (i - 1))))
      19. If CInt((dcb And x) >> (2 ^ (i - 1))) = 0 Then
      20. Destination(j) = br.ReadByte
      21. j += 1
      22. DataLeft -= 1
      23. Else
      24. Dim rPos As Integer, howManyByte As Integer
      25. Dim tmp As Integer = br.ReadUInt16
      26. Dim tmpRev As Integer = (tmp >> 8) + ((tmp And 255) << 8)
      27. howManyByte = ((tmpRev And 61440) >> 12) + 3
      28. rPos = (tmpRev And 4095) + 1
      29. For i2 = 0 To howManyByte - 1
      30. Destination(j + i2) = Destination(j - rPos + i2)
      31. DataLeft -= 1
      32. Next
      33. j += howManyByte
      34. End If
      35. Next
      36. End While
      37. Return Destination
      38. End Function
      39. End Class
      Alles anzeigen

      System.IO muss imported werden..

      mfG hack!osa

      Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von hack!osa ()

    • Hmm imo wäre es schöner einen Stream zu übergeben und ein dynamisches Byte Array in Form einer generic List zurück zu geben, denn dann wäre man nicht an Files gebunden sondern könnte u.A. auch einen MemoryStream oder sogar(Unnötigerweiße) einen NetworkStream Dekomprimieren. Außerdem: Ich bin zwar nicht mehr ganz so gewandt in VB, aber wenn du einen Destination Buffer benutzt solltest du denke ich eine Subroutine anstelle einer Function erstellen und den Pararmeter als out oder Referenz deklarieren, schöner wäre aber mmn. immernoch ein Rückgabewert. Deine Funktion könntest du außerdem statisch machen und in eine Klasse packen.

      ~Sturmvogel
    • Danke für das Feedback. Werd ich geich machen.
      Wollte eigentlich Ubuntu laden und installieren, aber das Inet spackt..

      EDIT: Code geupdated ;)
      Changelog:
      [+] Stream wird nun angegeben
      [+] Angabe eines Offset optional, standardmäßig 0
      [+] Größe des Arrays muss nicht vorher definiert sein
      [+] Unabhängig von Funktionen wie Dec2Bin
      [+] In einer Klasse vorhanden

      mfG hack!osa

      Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von hack!osa ()

    • Hallo,

      das ist sicher für einige brauchbar, für mich jetzt nicht, aber ich hätte noch zwei Vorschläge zum Codestil. Es wäre schön wenn du diese Dinge ändern würdest. :)

      1) In Zeile 14: 'On Error Resume Next' ist stark veraltet. In .NET nimmt man dafür eigentlich Try [...] Catch [...] End Try her. Mein Vorschlag wäre allerdings bei einem Fehler diesen Fehler auch in der Funktion durchgehen zu lassen - für den Benutzer wäre es sicher gut wenn er im Falle eines solchen weiß was schief gelaufen ist!
      2) Eher etwas unwichtiges, aber trotzdem ^^: In einer Funktion schreibt man Variablen normalerweise klein (also, hier z.B. DataLeft -> dataLeft). Das ist einfach zum Orientieren besser und allgemein so angewendet. Das ist, wie schon gesagt, nicht wichtig, wäre allerdings so ein Pluspunkt. :3

      Und noch ein paar Fehler in VS:
      - Bei 'Function' fehlt noch ein 'As Byte()', oder halt eine 'Sub'. So geht das sonst nicht!
      - Bei 'Option Strict On' in Zeile 19 und 20 gibt es noch Konvertierungsfehler, die solltest du vielleicht noch ausmerzen.

      Aber trotzdem, echt gute Arbeit. Ist sicher nützlich! :)

      lg

    • 1) In Zeile 14: 'On Error Resume Next' ist stark veraltet. In .NET nimmt man dafür eigentlich Try [...] Catch [...] End Try her. Mein Vorschlag wäre allerdings bei einem Fehler diesen Fehler auch in der Funktion durchgehen zu lassen - für den Benutzer wäre es sicher gut wenn er im Falle eines solchen weiß was schief gelaufen ist!

      Joah bin es halt noch von VB6 gewohnt. ^^


      2) Eher etwas unwichtiges, aber trotzdem : In einer Funktion schreibt man Variablen normalerweise klein (also, hier z.B. DataLeft -> dataLeft). Das ist einfach zum Orientieren besser und allgemein so angewendet. Das ist, wie schon gesagt, nicht wichtig, wäre allerdings so ein Pluspunkt. :3

      Naja haste recht ist jetzt nicht wirklich wichtig, kann ich aber gerne anpassen!


      Und noch ein paar Fehler in VS:
      - Bei 'Function' fehlt noch ein 'As Byte()', oder halt eine 'Sub'. So geht das sonst nicht!
      - Bei 'Option Strict On' in Zeile 19 und 20 gibt es noch Konvertierungsfehler, die solltest du vielleicht noch ausmerzen.

      Die beiden Sachen kann ich nicht verstehen, da der Code bei mir so einwandfrei läuft.


      Aber trotzdem, echt gute Arbeit. Ist sicher nützlich!

      Danke!

      Lg hack!osa
    • Hey,

      sorry, I do not happen to have a compression algorithm, since I never had the need for one. Though going from the decompression routine it shouldn't be too hard to create one. My general (though untested) approach would be to process the data to compress from begin to end and at each position look if the data at the current cursor also exists in the compression window (the area that can be addressed with an reference at that position). Then just place either a reference or the actual data in the compressed buffer!

      Kind Regards,
      hack!osa
    • Oh ok....

      I was able to create a decompression function in vb which accepted string and gave back string... (the need of string I/O came upto my head due to my readhex and writehex function which gave result as string)
      But i had simply made "byte array" <--> "string" conversion function as well.

      Now as you said I was also thinking of the same thing... but this really bored to get it dont today ;)
      I will try it out some other day as I am also not in a urgent need of it :)

      Thanks for the reply.

      Kind Regards,
      The_Learner!