2009-04-10 36 views
6

Nhiệm vụ của tôi là giải nén gói (đã nhận) bằng zlib và sau đó sử dụng thuật toán để tạo ảnh từ dữ liệuzlib từ C++ đến C# (Cách chuyển đổi byte [] thành luồng và luồng thành byte [])

Tin tốt lành là tôi có mã trong C++, nhưng nhiệm vụ là để làm điều đó trong C#

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; 
      } 
     } 

tôi đang cố gắng để làm điều này với zlib.NET, nhưng tất cả demo có mã đó để giải nén (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(); 
    } 

Vấn đề của tôi: Tôi không muốn lưu tệp sau khi giải nén, vì tôi phải sử dụng thuật toán được hiển thị trong mã C++.

Làm thế nào để chuyển đổi mảng byte [] thành một dòng tương tự như một trong mã zlib C# để giải nén dữ liệu và sau đó làm thế nào để chuyển đổi dòng trở lại thành mảng byte?

Ngoài ra, Cách thay đổi mã zlib.NET để KHÔNG lưu tệp?

+0

Cần chính xác như nhau. Cảm ơn! – lesderid

+0

Tôi muốn tặng một phần thưởng cho @JoshStribling - Tôi có thể làm điều đó vào ngày mai. –

Trả lời

10

Chỉ cần sử dụng MemoryStreams thay vì FileStreams:

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

Sau đó, bạn có thể sử dụng output.ToArray() sau đó để có được một mảng byte ra.

Lưu ý rằng tốt hơn là sử dụng các câu lệnh using thay vì một lần thử/cuối cùng - nếu không, nếu cuộc gọi đầu tiên đến Close không thành công, phần còn lại sẽ không được thực hiện. Bạn có thể lồng chúng như thế này:

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

Jon Skeet, tôi ngưỡng mộ cuốn sách bạn đã viết (C# trong chiều sâu). Bạn sẽ viết một cái khác khi C# v4 xuất hiện? –

+1

Không có gì là hoàn toàn cụ thể, nhưng tôi hy vọng sẽ viết một ấn bản thứ hai của C# trong chiều sâu để trang trải C# 4, vâng. Vui mừng bạn thích phiên bản đầu tiên :) –

5

Tôi vừa gặp vấn đề tương tự.

cho đầy đủ ... (vì đây bối rối cho tôi trong vài giờ)

Trong trường hợp của ZLib.Net bạn cũng phải gọi kết thúc(), mà thường xảy ra trong quá trình Close(), trước khi bạn gọi trở lại output.ToArray()

Nếu không, bạn sẽ nhận được một/mảng byte không đầy đủ trống từ dòng ký ức của bạn, bởi vì ZStream đã không thực sự bằng văn bản tất cả các dữ liệu được nêu ra:

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(); 
    } 
} 

trong ví dụ này tôi m cũng sử dụng không gian tên zlib:

using zlib; 

Nguyên tìm thấy trong luồng này: ZLib decompression

Tôi không có đủ điểm để bỏ phiếu lên được nêu ra, vì vậy ...

Nhờ Tim Greaves for the tip liên quan đến kết thúc trước khi ToArray

Và Jon Skeet để biết mẹo liên quan đến lồng các câu lệnh sử dụng cho luồng (mà tôi thích tốt hơn thử/cuối cùng)

+0

Cảm ơn rất nhiều! Đây là gợi ý tuyệt vời! –

+0

những gì là inData và outData ở đây ??? – pulkit

Các vấn đề liên quan