zlib von C ++ auf C # (Wie byte [] konvertieren zu streamen und [] Byte-Stream)

StackOverflow https://stackoverflow.com/questions/737258

  •  09-09-2019
  •  | 
  •  

Frage

Meine Aufgabe ist es, ein Paket (erhalten) mit zlib zu dekomprimieren und dann einen algoritm verwenden, um ein Bild aus den Daten zu machen

Die gute Nachricht ist, dass ich den Code in C ++, aber die Aufgabe ist es in C # zu tun

C ++

        //Read the first values of the packet received

        DWORD image[200 * 64] = {0}; //used for algoritm(width always = 200 and height always == 64)
        int imgIndex = 0; //used for algoritm
        unsigned char rawbytes_[131072] = {0}; //read below
        unsigned char * rawbytes = rawbytes_; //destrination parameter for decompression(ptr)
        compressed = r.Read<WORD>(); //the length of the compressed bytes(picture)
        uncompressed = r.Read<WORD>(); //the length that should be after decompression
        width = r.Read<WORD>(); //the width of the picture
        height = r.Read<WORD>(); //the height of the picture

        LPBYTE ptr = r.GetCurrentStream(); //the bytes(file that must be decompressed)

        outLen = uncompressed; //copy the len into another variable

        //Decompress

        if(uncompress((Bytef*)rawbytes, &outLen, ptr, compressed) != Z_OK)
        {
            printf("Could not uncompress the image code.\n");
            Disconnect();
            return;
        }

        //Algoritm to make up the picture
        // Loop through the data
        for(int c = 0; c < (int)height; ++c)
        {
            for(int r = 0; r < (int)width; ++r)
            {
                imgIndex = (height - 1 - c) * width + r;
                image[imgIndex] = 0xFF000000;
                if(-((1 << (0xFF & (r & 0x80000007))) & rawbytes[((c * width + r) >> 3)])) 
                    image[imgIndex] = 0xFFFFFFFF;
            }
        }

Ich versuche, dies mit zlib.NET zu tun, aber alle Demos haben diesen Code zu dekomprimieren (C #)

    private void decompressFile(string inFile, string outFile)
    {
        System.IO.FileStream outFileStream = new System.IO.FileStream(outFile, System.IO.FileMode.Create);
        zlib.ZOutputStream outZStream = new zlib.ZOutputStream(outFileStream);
        System.IO.FileStream inFileStream = new System.IO.FileStream(inFile, System.IO.FileMode.Open);          
        try
        {
            CopyStream(inFileStream, outZStream);
        }
        finally
        {
            outZStream.Close();
            outFileStream.Close();
            inFileStream.Close();
        }
    }

    public static void CopyStream(System.IO.Stream input, System.IO.Stream output)
    {
        byte[] buffer = new byte[2000];
        int len;
        while ((len = input.Read(buffer, 0, 2000)) > 0)
        {
            output.Write(buffer, 0, len);
        }
        output.Flush();
    }

Mein Problem: Ich mag nicht, um die Datei nach der Dekomprimierung speichern, weil ich die algoritm in dem C ++ Code gezeigt verwenden

.

Wie die byte [] Array in einen Strom ähnlich den in dem C # zlib-Code konvertieren, die Daten zu dekomprimieren und dann, wie der Strom wieder in Byte-Array zu konvertieren?

Auch, wie der zlib.NET Code ändern Dateien nicht speichern?

War es hilfreich?

Lösung

Verwenden Sie einfach MemoryStreams statt Filestreams:

// Assuming inputData is a byte[]
MemoryStream input = new MemoryStream(inputData);
MemoryStream output = new MemoryStream();

Dann können Sie output.ToArray() verwenden danach ein Byte-Array, um aus.

Beachten Sie, dass es in der Regel besser zu using Aussagen anstelle eines einzigen try / finally-Block zu verwenden - wie sonst, wenn der erste Aufruf von Close ausfällt, wird der Rest nicht vorgenommen werden. Sie können Nest sie wie folgt:

using (MemoryStream output = new MemoryStream())
using (Stream outZStream = new zlib.ZOutputStream(output))
using (Stream input = new MemoryStream(bytes))
{
    CopyStream(inFileStream, outZStream);
    return output.ToArray();
}

Andere Tipps

Ich lief in das gleiche Problem.

Für Vollständigkeits ... (da dies stapfte mich für mehrere Stunden)

Im Fall von ZLib.Net Sie auch beenden nennen haben (), die in der Regel während des Schließens geschieht (), bevor Sie zurück output.ToArray nennen ()

Andernfalls werden Sie einen leeren / unvollständigen Byte-Array von dem Speicherstrom erhalten, weil die zStream nicht tatsächlich alle Daten geschrieben noch:

public static void CompressData(byte[] inData, out byte[] outData)
{
    using (MemoryStream outMemoryStream = new MemoryStream())
    using (ZOutputStream outZStream = new ZOutputStream(outMemoryStream, zlibConst.Z_DEFAULT_COMPRESSION))
    using (Stream inMemoryStream = new MemoryStream(inData))
    {
        CopyStream(inMemoryStream, outZStream);
        outZStream.finish();
        outData = outMemoryStream.ToArray();
    }
}

public static void DecompressData(byte[] inData, out byte[] outData)
{
    using (MemoryStream outMemoryStream = new MemoryStream())
    using (ZOutputStream outZStream = new ZOutputStream(outMemoryStream))
    using (Stream inMemoryStream = new MemoryStream(inData))
    {
        CopyStream(inMemoryStream, outZStream);
        outZStream.finish();
        outData = outMemoryStream.ToArray();
    }
}

In diesem Beispiel verwende ich auch den zlib-Namespace:

using zlib;

Ursprünglich in diesem Thread gefunden: ZLib Dekompression

Ich habe nicht genug Punkte noch stimmen, also ...

Dank Tim Greaves für die Spitze vor ToArray bezüglich Finish

Und Jon Skeet für die Spitze in Bezug auf die Verwendung von Aussagen für Ströme nisten (was ich viel besser gefällt als try / finally)

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top