Created
April 11, 2012 06:58
-
-
Save ymmt2005/2357455 to your computer and use it in GitHub Desktop.
xz block encode/decode
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "util.hpp" | |
#include <Poco/File.h> | |
#include <lzma.h> | |
#include <vector> | |
#include <iostream> | |
#include <cstddef> | |
#include <cstring> | |
#include <cstdlib> | |
const uint32_t COMPRESSION_LEVEL = 6; | |
const lzma_check INTEGRITY_CHECK = LZMA_CHECK_CRC64; | |
const lzma_match_finder FINDER = LZMA_MF_HC4; | |
const std::size_t BUFSIZ = 2 * 1024 * 1024; | |
void usage() { | |
std::cerr << "Usage: test_lzma INFILE" << std::endl; | |
} | |
int main(int argc, char** argv) { | |
if( argc == 1 ) { | |
usage(); | |
return 1; | |
} | |
lzma_options_lzma options; | |
lzma_lzma_preset(&options, COMPRESSION_LEVEL); | |
options.mf = FINDER; | |
std::size_t ENCODED_BUFSIZ = lzma_block_buffer_bound(BUFSIZ); | |
std::cerr << "max encoded size=" << ENCODED_BUFSIZ << std::endl; | |
std::vector<uint8_t> buf(BUFSIZ); | |
uint8_t* const pBuf = &(buf[0]); | |
std::vector<uint8_t> ebuf(ENCODED_BUFSIZ); | |
uint8_t* const pEbuf = &(ebuf[0]); | |
cybozu::file f(Poco::Path(argv[1]), O_RDONLY); | |
#if 0 | |
lzma_filter filters[LZMA_FILTERS_MAX + 1]; | |
filters[0].id = LZMA_FILTER_LZMA2; | |
filters[0].options = &options; | |
filters[1].id = LZMA_VLI_UNKNOWN; | |
filters[1].options = 0; | |
uint64_t memory_usage = lzma_raw_encoder_memusage(filters); | |
if( memory_usage == UINT64_MAX ) { | |
std::cerr << "failed to check memory usage of encoder." << std::endl; | |
return 1; | |
} | |
std::cerr << "encoder mem usage=" << memory_usage << std::endl; | |
lzma_block block_header; | |
std::memset(&block_header, 0, sizeof(block_header)); | |
block_header.version = 0; | |
block_header.check = INTEGRITY_CHECK; | |
block_header.filters = filters; | |
f.read(pBuf, BUFSIZ); | |
std::size_t out_pos = 0; | |
if( lzma_block_buffer_encode(&block_header, NULL, pBuf, BUFSIZ, | |
pEbuf, &out_pos, ENCODED_BUFSIZ) != LZMA_OK ) { | |
std::cerr << "failed to encode." << std::endl; | |
return 1; | |
} | |
std::cerr << "encoded size=" << out_pos << std::endl; | |
cybozu::writeall(1, pEbuf, out_pos); | |
#else | |
std::size_t len = (std::size_t)Poco::File(argv[1]).getSize(); | |
f.read(pEbuf, len); | |
lzma_filter filters[LZMA_FILTERS_MAX + 1]; | |
for( int i = 0; i < (LZMA_FILTERS_MAX+1); ++i ) { | |
filters[i].id = LZMA_VLI_UNKNOWN; | |
filters[i].options = 0; | |
} | |
lzma_block block_header; | |
std::memset(&block_header, 0, sizeof(block_header)); | |
block_header.version = 0; | |
block_header.filters = filters; | |
block_header.header_size = lzma_block_header_size_decode(pEbuf[0]); | |
std::size_t in_pos = (std::size_t)block_header.header_size; | |
std::cerr << "block header size=" << in_pos << std::endl; | |
if( lzma_block_header_decode(&block_header, NULL, pEbuf) != LZMA_OK ) { | |
std::cerr << "failed to decode header." << std::endl; | |
return 1; | |
} | |
uint64_t memory_usage = lzma_raw_decoder_memusage(filters); | |
if( memory_usage == UINT64_MAX ) { | |
std::cerr << "failed to check memory usage of decoder." << std::endl; | |
return 1; | |
} | |
std::cerr << "decoder mem usage=" << memory_usage << std::endl; | |
std::size_t out_pos = 0; | |
if( lzma_block_buffer_decode(&block_header, NULL, pEbuf, &in_pos, len, | |
pBuf, &out_pos, BUFSIZ) != LZMA_OK ) { | |
std::cerr << "failed to decode." << std::endl; | |
return 1; | |
} | |
std::cerr << "decoded size=" << out_pos << std::endl; | |
for( int i = 0; i < (LZMA_FILTERS_MAX + 1); ++i ) { | |
if( filters[i].id == LZMA_VLI_UNKNOWN ) break; | |
std::free( filters[i].options ); | |
filters[i].options = 0; | |
} | |
cybozu::writeall(1, pBuf, out_pos); | |
#endif | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment