如何使用 Fast-LZMA2 高级功能内存和选项的管理

问题描述

我想通过 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);