示例#1
0
bool inno_lzma1_decompressor_impl::filter(const char * & begin_in, const char * end_in,
                                          char * & begin_out, char * end_out, bool flush) {
	
	// Decode the header.
	if(!stream) {
		
		// Read enough bytes to decode the header.
		while(nread != 5) {
			if(begin_in == end_in) {
				return true;
			}
			header[nread++] = *begin_in++;
		}
		
		lzma_options_lzma options;
		
		uint8_t properties = uint8_t(header[0]);
		if(properties > (9 * 5 * 5)) {
			throw lzma_error("inno lzma1 property error", LZMA_FORMAT_ERROR);
		}
		options.pb = properties / (9 * 5);
		options.lp = (properties % (9 * 5)) / 9;
		options.lc = properties % 9;
		
		options.dict_size = 0;
		for(size_t i = 0; i < 4; i++) {
			options.dict_size += uint32_t(uint8_t(header[i + 1])) << (i * 8);
		}
		
		stream = init_raw_lzma_stream(LZMA_FILTER_LZMA1, options);
	}
	
	return lzma_decompressor_impl_base::filter(begin_in, end_in, begin_out, end_out, flush);
}
示例#2
0
bool inno_lzma2_decompressor_impl::filter(const char * & begin_in, const char * end_in,
                                          char * & begin_out, char * end_out, bool flush) {
	
	// Decode the header.
	if(!stream) {
		
		if(begin_in == end_in) {
			return true;
		}
		
		lzma_options_lzma options;
		
		uint8_t prop = uint8_t(*begin_in++);
		if(prop > 40) {
			throw lzma_error("inno lzma2 property error", LZMA_FORMAT_ERROR);
		}
		
		if(prop == 40) {
			options.dict_size = 0xffffffff;
		} else {
			options.dict_size = ((uint32_t(2) | uint32_t((prop) & 1)) << ((prop) / 2 + 11));
		}
		
		stream = init_raw_lzma_stream(LZMA_FILTER_LZMA2, options);
	}
	
	return lzma_decompressor_impl_base::filter(begin_in, end_in, begin_out, end_out, flush);
}
void lzma_error::check( int error )
{
	switch ( error ) {
	case LZMA_OK:
	case LZMA_STREAM_END:
		return;
	case LZMA_MEM_ERROR:
		throw std::bad_alloc();
	default:
		throw lzma_error( error );
	}
}
示例#4
0
static lzma_stream * init_raw_lzma_stream(lzma_vli filter, lzma_options_lzma & options) {
	
	options.preset_dict = NULL;
	
	if(options.dict_size > (uint32_t(1) << 28)) {
		throw lzma_error("inno lzma dict size too large", LZMA_FORMAT_ERROR);
	}
	
	lzma_stream * strm = new lzma_stream;
	lzma_stream tmp = LZMA_STREAM_INIT;
	*strm = tmp;
	strm->allocator = NULL;
	
	const lzma_filter filters[2] = { { filter,  &options }, { LZMA_VLI_UNKNOWN, NULL } };
	lzma_ret ret = lzma_raw_decoder(strm, filters);
	if(ret != LZMA_OK) {
		delete strm;
		throw lzma_error("inno lzma init error", ret);
	}
	
	return strm;
}
示例#5
0
Array<uint8_t> compress(RawArray<const uint8_t> data, int level, event_t event) {
  thread_time_t time(compress_kind,event);
  if (level<20) { // zlib
    size_t dest_size = compressBound(data.size());
    Array<uint8_t> compressed(CHECK_CAST_INT(dest_size),uninit);
    int z = compress2(compressed.data(),&dest_size,(uint8_t*)data.data(),data.size(),level);
    if (z!=Z_OK)
      THROW(IOError,"zlib failure in compress_and_write: %s",zlib_error(z));
    return compressed.slice_own(0,CHECK_CAST_INT(dest_size));
  } else { // lzma
    size_t dest_size = lzma_stream_buffer_bound(data.size());
    Array<uint8_t> compressed(CHECK_CAST_INT(dest_size),uninit);
    size_t pos = 0;
    lzma_ret r = lzma_easy_buffer_encode(level-20,LZMA_CHECK_CRC64,0,data.data(),data.size(),compressed.data(),&pos,dest_size);
    if (r!=LZMA_OK)
      THROW(RuntimeError,"lzma compression error: %s (%d)",lzma_error(r),r);
    return compressed.slice_own(0,CHECK_CAST_INT(pos));
  }
}
示例#6
0
Array<uint8_t> decompress(RawArray<const uint8_t> compressed, const size_t uncompressed_size, event_t event) {
  GEODE_ASSERT(uncompressed_size<(uint64_t)1<<31);
  thread_time_t time(decompress_kind,event);
  size_t dest_size = uncompressed_size;
  Array<uint8_t> uncompressed = aligned_buffer<uint8_t>(CHECK_CAST_INT(dest_size));
  if (!is_lzma(compressed)) { // zlib
    int z = uncompress((uint8_t*)uncompressed.data(),&dest_size,compressed.data(),compressed.size());
    if (z!=Z_OK)
      THROW(IOError,"zlib failure in read_and_uncompress: %s",zlib_error(z));
  } else { // lzma
    const uint32_t flags = LZMA_TELL_NO_CHECK | LZMA_TELL_UNSUPPORTED_CHECK;
    uint64_t memlimit = UINT64_MAX;
    size_t in_pos = 0, out_pos = 0;
    lzma_ret r = lzma_stream_buffer_decode(&memlimit,flags,0,compressed.data(),&in_pos,compressed.size(),uncompressed.data(),&out_pos,dest_size);
    if (r!=LZMA_OK)
      THROW(IOError,"lzma failure in read_and_uncompress: %s (%d)",lzma_error(r),r);
  }
  if (dest_size != uncompressed_size)
    THROW(IOError,"read_and_compress: expected uncompressed size %zu, got %zu",uncompressed_size,dest_size);
  return uncompressed;
}
示例#7
0
bool lzma_decompressor_impl_base::filter(const char * & begin_in, const char * end_in,
                                         char * & begin_out, char * end_out, bool flush) {
	(void)flush;
	
	lzma_stream * strm = static_cast<lzma_stream *>(stream);
	
	strm->next_in = reinterpret_cast<const uint8_t *>(begin_in);
	strm->avail_in = size_t(end_in - begin_in);
	
	strm->next_out = reinterpret_cast<uint8_t *>(begin_out);
	strm->avail_out = size_t(end_out - begin_out);
	
	lzma_ret ret = lzma_code(strm, LZMA_RUN);
	
	begin_in = reinterpret_cast<const char *>(strm->next_in);
	begin_out = reinterpret_cast<char *>(strm->next_out);
	
	if(ret != LZMA_OK && ret != LZMA_STREAM_END && ret != LZMA_BUF_ERROR) {
		throw lzma_error("lzma decrompression error", ret);
	}
	
	return (ret != LZMA_STREAM_END);
}