2017-04-07 63 views
0

我目前正在嘗試解壓縮targa(RGB24_RLE)圖像數據。Targa遊程長度編碼

我的算法是這樣的:

static constexpr size_t kPacketHeaderSize = sizeof(char); 

     //http://paulbourke.net/dataformats/tga/ 
     inline void DecompressRLE(unsigned int a_BytePerPixel, std::vector<CrByte>& a_In, std::vector<CrByte>& a_Out) 
     { 
      for (auto it = a_In.begin(); it != a_In.end();) 
      { 
       //Read packet header 
       int header = *it & 0xFF; 
       int count = (header & 0x7F) + 1; 

       if ((header & 0x80) != 0) //packet type 
       { 
        //For the run length packet, the header is followed by 
        //a single color value, which is assumed to be repeated 
        //the number of times specified in the header. 

        auto paStart = it + kPacketHeaderSize; 
        auto paEnd = paStart + a_BytePerPixel; 

        //Insert packets into output buffer 
        for (size_t pk = 0; pk < count; ++pk) 
        { 
         a_Out.insert(a_Out.end(), paStart, paEnd); 
        } 

        //Jump to next header 
        std::advance(it, kPacketHeaderSize + a_BytePerPixel); 
       } 
       else 
       { 
        //For the raw packet, the header s followed by 
        //the number of color values specified in the header. 

        auto paStart = it + kPacketHeaderSize; 
        auto paEnd = paStart + count * a_BytePerPixel; 

        //Insert packets into output buffer 
        a_Out.insert(a_Out.end(), paStart, paEnd); 

        //Jump to next header 
        std::advance(it, kPacketHeaderSize + count * a_BytePerPixel); 
       } 
      } 
     } 

在此呼籲:

//Read compressed data 
std::vector<CrByte> compressed(imageSize); 
ifs.seekg(sizeof(Header), std::ifstream::beg); 
ifs.read(reinterpret_cast<char*>(compressed.data()), imageSize); 

//Decompress 
std::vector<CrByte> decompressed(imageSize); 
DecompressRLE(bytePerPixel, compressed, decompressed); 

imageSize的定義是這樣的:

size_t imageSize = hd.width * hd.height * bytePerPixel 

然而,DecompressRLE()完成後(這需要很長的時間與2048x2048紋理)解壓仍然是空的/只包含零。也許我錯過了某些東西。

count有時似乎不合理地高,我認爲這是不正常的。 compressedSize應該小於imageSize,否則它不會被壓縮。但是,使用ifstream::tellg()會給我錯誤的結果。 有什麼幫助嗎?

回答

1

如果仔細查看調試器中的變量,您會看到std::vector<CrByte> decompressed(imageSize);聲明瞭一個帶有imageSize元素的向量。然後在DecompressRLE中插入該矢量的末尾,導致它增長。這就是爲什麼你的解壓縮圖像充滿了零,並且爲什麼它需要這麼長時間(因爲矢量會週期性地調整大小)。

你想要做什麼是預留的空間:

std::vector<CrByte> decompressed; 
decompressed.reserve(imageSize); 

你的壓縮緩衝看起來是不是文件內容較大,所以你還是過去解壓文件的末尾。壓縮文件的大小應該在Header。用它。

+0

謝謝! 「壓縮的文件大小應該在標題中。」你的頭是什麼意思? targa頭文件或運行長度數據包頭文件? – mutex36

+0

@ mutex36 targa頭文件。 – 1201ProgramAlarm

+0

根據[本規範](http://paulbourke.net/dataformats/tga/),標題中沒有指定壓縮大小?只是寬度和高度,它等於最終的未壓縮圖像的寬度和高度。 – mutex36