2017-04-07 4 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 텍스처 포함) 압축 해제는 여전히 비어 있으며 0 만 포함됩니다. 어쩌면 내가 밖으로 somehting을 놓치고있다.

count 가끔 비정상적으로 높은 것 같아서 이상하다고 생각합니다. compressedSize이 imageSize보다 작아야합니다. 그렇지 않으면 이미지가 압축되지 않습니다. 그러나 ifstream::tellg()을 사용하면 잘못된 결과가 나옵니다. 도움이 되었습니까?

답변

1

디버거에서 변수를 자세히 살펴보면 은 imageSize 요소가있는 벡터를 선언한다는 것을 알 수 있습니다. 그런 다음 DecompressRLE에서 해당 벡터의 끝 부분에 삽입하여 증가시킵니다. 이것이 압축 해제 된 이미지가 0으로 가득 차있는 이유이며 왜 벡터가 주기적으로 크기가 조정되므로 너무 오래 걸리는 이유입니다. 당신이 원하는 무엇

은 공간을 예약입니다 :이 파일 내용보다 더 큰 것처럼

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

압축 된 버퍼가 보이는, 그래서 당신은 여전히 ​​파일의 끝을지나 압축 해제하고 있습니다. 압축 파일 크기는 Header이어야합니다. 그걸 써.

+0

감사! "압축 파일 크기가 헤더에 있어야합니다." 어떤 헤더를 의미합니까? targa 헤더 또는 런 길이 패킷 헤더? – mutex36

+0

@ mutex36 targa 헤더입니다. – 1201ProgramAlarm

+0

[이 사양] (http://paulbourke.net/dataformats/tga/)에 따르면 헤더에 압축 된 크기가 지정되어 있지 않습니까? width와 height는 압축되지 않은 최종 이미지의 너비와 높이와 같습니다. – mutex36