示例#1
0
void LZ4Segment<T>::_decompress_block_to_bytes(const size_t block_index, std::vector<char>& decompressed_data,
                                               const size_t write_offset) const {
  const auto decompressed_block_size = block_index + 1 != _lz4_blocks.size() ? _block_size : _last_block_size;
  auto& compressed_block = _lz4_blocks[block_index];
  const auto compressed_block_size = compressed_block.size();

  int decompressed_result;
  if (_dictionary.empty()) {
    /**
     * If the dictionary is empty, we either have only a single block or had not enough data for a dictionary.
     * When decoding without a dictionary LZ4 needs a stream decode pointer (which would be used to decode the
     * following blocks).
     * A new decoder needs to be created for every block (in the case of multiple blocks being compressed without a
     * dictionary) since the blocks were compressed independently.
     * This decoder needs to be reset via LZ4_setStreamDecode since LZ4 reuses the previous state instead.
     */
    LZ4_streamDecode_t lz4_stream_decoder;
    auto lz4_stream_decoder_ptr = std::make_unique<LZ4_streamDecode_t>(lz4_stream_decoder);
    const auto reset_decoder_status = LZ4_setStreamDecode(lz4_stream_decoder_ptr.get(), nullptr, 0);
    Assert(reset_decoder_status == 1, "LZ4 decompression failed to reset stream decoder.");

    decompressed_result = LZ4_decompress_safe_continue(
        lz4_stream_decoder_ptr.get(), compressed_block.data(), decompressed_data.data() + write_offset,
        static_cast<int>(compressed_block_size), static_cast<int>(decompressed_block_size));
  } else {
    decompressed_result = LZ4_decompress_safe_usingDict(
        compressed_block.data(), decompressed_data.data() + write_offset, static_cast<int>(compressed_block_size),
        static_cast<int>(decompressed_block_size), _dictionary.data(), static_cast<int>(_dictionary.size()));
  }

  Assert(decompressed_result > 0, "LZ4 stream decompression failed");
  DebugAssert(static_cast<size_t>(decompressed_result) == decompressed_block_size,
              "Decompressed LZ4 block has different size than the initial source data.");
}
示例#2
0
文件: lz4io.cpp 项目: cgmb/renderdoc
LZ4Decompressor::LZ4Decompressor(StreamReader *read, Ownership own) : Decompressor(read, own)
{
  m_Page[0] = AllocAlignedBuffer(lz4BlockSize);
  m_Page[1] = AllocAlignedBuffer(lz4BlockSize);
  m_CompressBuffer = AllocAlignedBuffer(LZ4_COMPRESSBOUND(lz4BlockSize));

  m_PageOffset = 0;
  m_PageLength = 0;

  LZ4_setStreamDecode(&m_LZ4Decomp, NULL, 0);
}
示例#3
0
文件: lz4.c 项目: NekBox/NekBox
void lz4_unpack(void * in, const size_t * const compSize, void * const out, int * const size, const int * const ierr) {
  size_t offset=0;
  size_t offset_in=0;
  decBufIndex=0;
  LZ4_resetStream(lz4Stream);
  LZ4_setStreamDecode(lz4StreamDecode,NULL,0);
  for(;;) {
    char cmpBuf[LZ4_COMPRESSBOUND(BLOCK_BYTES)];
    int cmpBytes = 0;
    /*printf("offset_in+sizeof(cmpBytes): %d\n",offset_in+sizeof(cmpBytes));*/
    /*printf("compSize: %d\n",*compSize);*/
    int tmp=offset_in+sizeof(cmpBytes);
    /*printf("tmp: %d\n", tmp);*/
    /*printf("compSize: %d\n", *compSize);*/
    if(tmp > (int) *compSize) {
      break;
    }
    memcpy(&cmpBytes, in+offset_in, sizeof(cmpBytes));
    /*printf("cmpBytes: %d\n",cmpBytes);*/
    if(cmpBytes <= 0) {
      /*printf("cmpBytes %d\n", cmpBytes);*/
      break;
    }

    /*printf("lz4 cmpBytes %d\n", cmpBytes);*/
    memcpy(&cmpBuf, in+offset_in+sizeof(cmpBytes), cmpBytes);
    const size_t readCount1=0;
    offset_in=offset_in+sizeof(cmpBytes)+cmpBytes;
    /*printf("new offset_in: %zu\n", offset_in);*/

    {
      char* decPtr = decBuf[decBufIndex];
      int decBytes = LZ4_decompress_safe_continue(
          lz4StreamDecode, cmpBuf, decPtr, cmpBytes, BLOCK_BYTES);
      if(decBytes <= 0) {
        /*printf("lz4 decBytes: %d\n", decBytes);*/
        break;
      }
      memcpy(out+offset, decPtr, (size_t) decBytes);
      offset=offset+(size_t) decBytes;
    }
    decBufIndex = (decBufIndex + 1) % 2;
  }
  *size=offset;
}
void test_decompress(FILE* outFp, FILE* inpFp)
{
    LZ4_streamDecode_t lz4StreamDecode_body;
    LZ4_streamDecode_t* lz4StreamDecode = &lz4StreamDecode_body;

    char decBuf[2][BLOCK_BYTES];
    int  decBufIndex = 0;

    LZ4_setStreamDecode(lz4StreamDecode, NULL, 0);

    for(;;) {
        char cmpBuf[LZ4_COMPRESSBOUND(BLOCK_BYTES)];
        int  cmpBytes = 0;

        {
            const size_t readCount0 = read_int(inpFp, &cmpBytes);
            if(readCount0 != 1 || cmpBytes <= 0) {
                break;
            }

            const size_t readCount1 = read_bin(inpFp, cmpBuf, (size_t) cmpBytes);
            if(readCount1 != (size_t) cmpBytes) {
                break;
            }
        }

        {
            char* const decPtr = decBuf[decBufIndex];
            const int decBytes = LZ4_decompress_safe_continue(
                lz4StreamDecode, cmpBuf, decPtr, cmpBytes, BLOCK_BYTES);
            if(decBytes <= 0) {
                break;
            }
            write_bin(outFp, decPtr, (size_t) decBytes);
        }

        decBufIndex = (decBufIndex + 1) % 2;
    }
}
void decompressFile(FILE* outFp, FILE* inpFp)
{
    LZ4_streamDecode_t lz4StreamDecode_body;
    LZ4_streamDecode_t* lz4StreamDecode = &lz4StreamDecode_body;

    char decBuf[2][BLOCK_BYTES];
    int  decBufIndex = 0;

    LZ4_setStreamDecode(lz4StreamDecode, NULL, 0);

    while(1)
    {
        char cmpBuf[LZ4_COMPRESSBOUND(BLOCK_BYTES)];
        int  cmpBytes = 0;

        {
            const size_t readCount0 = intRead(inpFp, &cmpBytes);
            if((readCount0 != 1) || (cmpBytes <= 0))
            {
                break;
            }
            const size_t readCount1 = binRead(inpFp, cmpBuf, (size_t) cmpBytes);
            if(readCount1 != (size_t) cmpBytes)
            {
                break;
            }
        }
        {
            char* const decPtr = decBuf[decBufIndex];
            const int decBytes = LZ4_decompress_safe_continue(lz4StreamDecode, cmpBuf, decPtr, cmpBytes, BLOCK_BYTES);
            if(decBytes <= 0)
            {
                break;
            }
            binWrite(outFp, decPtr, (size_t) decBytes);
        }
        decBufIndex = (decBufIndex + 1) % 2;
    }
}