Search code examples
vb.netzlibdeflatestream

zLib decompress from string not file to DeflateStream


I've been trying for 2 weeks to uncompress this user-defined TXXX string from an MP3 ID2,3 file.

000000B0789C6330377433D63534D575F3F737B570343767B02929CA2C4B2D4BCD2B29B6B301D376367989B9A976C519F9E50ACE1989452536FA60019B924C20696800017A10CA461F2C6AA30FD58A61427E5E72AA42228A114666E6F88CD047721100D5923799

Thanks to Dr. Adler for the correct answer when I converted the values to a string.

  1. I have tried both MS DeflateStream and GZipstream with no success.

  2. Every example I see uses a stream file. I am not using a file, I have the above zLib code in both an array or string variable.

  3. GZipstream gives me 'no magic number' and Deflatestream gives me 'Block length does not match with its complement'.

  4. I read this post: http://george.chiramattel.com/blog/2007/09/deflatestream-block-length-does-not-match.html

  5. tried removing bytes from the head, no luck. (I read trazillions of articles for sending a string to Deflatestream but again 'no luck'!

I have the above string, so how do I send it to Deflatestream? I'd post the two hundred different code examples I tried but that would be silly.

The funny thing is, I built my webAudio cue marker editor in less than two weeks and this is the last thing I have it do (my program must get the marker positions from a program that has worst audio editor known to man (they embedded them in the MP3 for some (bad) reason). Hence, I wrote my own to change audio cue marker so I could save hours of frustration at work. However, I'm not getting much sleep lately.

Help me get some sleep, please.


Solution

  • You can use a MemoryStream instead of a FileStream as they are both Streams:

    Imports System.IO
    Imports System.IO.Compression
    Imports System.Text
    
    Module Module1
    
        Function HexStringToBytes(s As String) As Byte()
            If (s.Length And 1) = 1 Then
                Throw New ArgumentException("String is an odd number of characters in length - it must be even.")
            End If
            Dim bb As New List(Of Byte)
            For i = 0 To s.Length - 1 Step 2
                bb.Add(Convert.ToByte(s.Substring(i, 2), 16))
            Next
            Return bb.ToArray()
    
        End Function
    
        Sub Main()
            Dim s = "000000B0789C6330377433D63534D575F3F737B570343767B02929CA2C4B2D4BCD2B29B6B301D376367989B9A976C519F9E50ACE1989452536FA60019B924C20696800017A10CA461F2C6AA30FD58A61427E5E72AA42228A114666E6F88CD047721100D5923799"
    
            Dim result As String = ""
    
            ' trim off the leading zero bytes and skip the three bytes 0xB0 0x78 0x9C
            Dim buffer = HexStringToBytes(s).SkipWhile(Function(b) b = 0).Skip(3).ToArray()
    
            Using ms As New MemoryStream(buffer)
                Using decompressedMemoryStream As New MemoryStream
                    Using decompressionStream As New DeflateStream(ms, CompressionMode.Decompress)
                        decompressionStream.CopyTo(decompressedMemoryStream)
                        result = Encoding.Default.GetString((decompressedMemoryStream.ToArray()))
                    End Using
                End Using
            End Using
    
            Console.WriteLine(result)
    
            Console.ReadLine()
    
        End Sub
    
    End Module
    

    Outputs:

      71F3-15-FOO58A77 <trivevents><event><name>show Chart</name><time>10000000.000000</time></event><event><name>show once a</name><time>26700000.000000</time></event></trivevents>
    

    (There is a leading zero byte.)

    P.S. It looks a bit strange that there is 71F3-15-FOO58A77 with letter Os instead of zeros.

    P.P.S. If you could get the compressed data into a Base64 string instead of a hex string, you could pack more data into the same space.