问题描述
我想通过 7Zip 使用 fast-LZMA2 压缩/解压缩无符号字符缓冲区:https://github.com/conor42/fast-lzma2
示例中有两个函数:
static int compress_file(FL2_CStream *fcs)
{
unsigned char in_buffer[8 * 1024];
unsigned char out_buffer[4 * 1024];
FL2_inBuffer in_buf = { in_buffer,sizeof(in_buffer),sizeof(in_buffer) };
FL2_outBuffer out_buf = { out_buffer,sizeof(out_buffer),0 };
size_t res = 0;
size_t in_size = 0;
size_t out_size = 0;
do {
if (in_buf.pos == in_buf.size) {
in_buf.size = fread(in_buffer,1,fin);
in_size += in_buf.size;
in_buf.pos = 0;
}
res = FL2_compressstream(fcs,&out_buf,&in_buf);
if (FL2_isError(res))
goto error_out;
fwrite(out_buf.dst,out_buf.pos,fout);
out_size += out_buf.pos;
out_buf.pos = 0;
} while (in_buf.size == sizeof(in_buffer));
do {
res = FL2_endStream(fcs,&out_buf);
if (FL2_isError(res))
goto error_out;
fwrite(out_buf.dst,fout);
out_size += out_buf.pos;
out_buf.pos = 0;
} while (res);
fprintf(stdout,"\t%ld -> %ld\n",in_size,out_size);
return 0;
error_out:
fprintf(stderr,"Error: %s\n",FL2_getErrorName(res));
return 1;
}
static int decompress_file(FL2_DStream *fds)
{
unsigned char in_buffer[4 * 1024];
unsigned char out_buffer[8 * 1024];
FL2_inBuffer in_buf = { in_buffer,0 };
size_t res;
size_t in_size = 0;
size_t out_size = 0;
do {
if (in_buf.pos == in_buf.size) {
in_buf.size = fread(in_buffer,fout);
in_size += in_buf.size;
in_buf.pos = 0;
}
res = FL2_decompressstream(fds,&in_buf);
if (FL2_isError(res))
goto error_out;
/* discard the output. XXhash will verify the integrity. */
out_size += out_buf.pos;
out_buf.pos = 0;
} while (res && in_buf.size);
fprintf(stdout,FL2_getErrorName(res));
return 1;
}
但我不知道如何使它与缓冲区一起工作并且没有像 8*1024 这样的大小限制 像 zlib deflate 压缩。
我想要类似的东西
LZMA2_Compress(void* buffer,size_t bufferSize);
和LZMA2_Decompress(void* buffer,size_t bufferSize);
我想在一些大文件上使用这个算法,Fast LZMA2 是我发现的最快的高比率压缩,请不要建议我使用其他方法。
这是我的测试代码,它可以工作,但只需要更正信息: https://gist.github.com/Bit00009/3241bb66301f8aaba16074537d094e61
解决方法
检查所有可用函数的头文件。这个看起来像你需要的。您需要将缓冲区转换为 (void *)
。
高级功能
fast-lzma2.h
...
/*! FL2_compress() :
* Compresses `src` content as a single LZMA2 compressed stream into already allocated `dst`.
* Call FL2_compressMt() to use > 1 thread. Specify nbThreads = 0 to use all cores.
* @return : compressed size written into `dst` (<= `dstCapacity),* or an error code if it fails (which can be tested using FL2_isError()). */
FL2LIB_API size_t FL2LIB_CALL FL2_compress(void* dst,size_t dstCapacity,const void* src,size_t srcSize,int compressionLevel);
...
内存和选项的管理
要进行显式内存管理(设置字典大小、缓冲区大小等),您需要创建一个上下文:
fast-lzma2.h
/*= Compression context
* When compressing many times,it is recommended to allocate a context just once,* and re-use it for each successive compression operation. This will make workload
* friendlier for system's memory. The context may not use the number of threads requested
* if the library is compiled for single-threaded compression or nbThreads > FL2_MAXTHREADS.
* Call FL2_getCCtxThreadCount to obtain the actual number allocated. */
typedef struct FL2_CCtx_s FL2_CCtx;
FL2LIB_API FL2_CCtx* FL2LIB_CALL FL2_createCCtx(void);
您可以使用 FL2_CCtx_setParameter()
在上下文中设置参数。 FL2_cParameter
中列出了参数的可能值,值 FL2_p_dictionarySize
将允许您设置字典大小。
/*! FL2_CCtx_setParameter() :
* Set one compression parameter,selected by enum FL2_cParameter.
* @result : informational value (typically,the one being set,possibly corrected),* or an error code (which can be tested with FL2_isError()). */
FL2LIB_API size_t FL2LIB_CALL FL2_CCtx_setParameter(FL2_CCtx* cctx,FL2_cParameter param,size_t value);
最后您可以通过调用 FL2_compressCCtx()
/*! FL2_compressCCtx() :
* Same as FL2_compress(),but requires an allocated FL2_CCtx (see FL2_createCCtx()). */
FL2LIB_API size_t FL2LIB_CALL FL2_compressCCtx(FL2_CCtx* cctx,void* dst,int compressionLevel);