1.1. 下载安装
下载 libbrotli, brotli
如果虚拟机可以上网,clone libbrotli 之后,就可以使用 autogen.sh 直接编译
git clone https://github.com/bagder/libbrotli
cd libbrotli
./autogen.sh && ./configure && make && make install
如果虚拟机不能上网,可以将 brotli 也下载好之后,直接放在 libbrotli 的目录之下,目录结构:libbrotli/brotli/c
git clone https://github.com/bagder/libbrotli
git clone https://github.com/google/brotli.git
cd libbrotli
# ll brotli/c
./autogen.sh && ./configure && make && make install
1.1.1. 编译问题解决
- Makefile.am: C objects in subdir but
AM_PROG_CC_C_O' not in
configure.ac' - Libtool library used but `LIBTOOL' is undefined,我在centos6的环境下编译通过,在centos5的环境下没有编译通过(没有特别去搞el5的环境,猜测可能需要升级libtool)。
在configure.am中添加 AM_PROG_CC_C_O
AC_PROG_CC
AM_PROG_CC_C_O
1.2. 编译示例代码
上面的编译过程之后,会生成了对应的静态库和动态库,在 libbrotli 目录的 .libs 目录下。也可以直接使用过来作为库的方式加载。(后续准备写一个简单的测试例子来验证)
gcc -g -o brotli brotli.c -I. -I. -I.. -I../brotli/c/include ../.libs/libbrotlienc.so ../.libs/libbrotlidec.so -lm
gcc -g -o brotli brotli.c -I. -I. -I.. -I../brotli/c/include libbrotlienc.a libbrotlidec.a -lm
1.3. 应用实例
# 压缩:压缩等级从0-11
time brotli -q 0 /www/docs/100M.file -o 100M.file.C
real 0m0.344s
user 0m0.271s
sys 0m0.072s
# 解压
time brotli -d 100M.file.C -o 100M.file
real 0m0.552s
user 0m0.392s
sys 0m0.159s
# 最终处理结果
ll 100M.file* -h
-rw-r--r-- 1 root root 100M Nov 6 2018 100M.file
-rw-r--r-- 1 root root 89K Nov 6 2018 100M.file.C
1.4. 使用源码生成动静态库
./autogen.sh && ./configure --prefix=/home/xxx/brotli/libbrotli-master/target && make && make install
ll target/lib/*
-rw-r--r-- 1 root root 487628 Aug 16 11:19 target/lib/libbrotlidec.a
-rw-r--r-- 1 root root 3466066 Aug 16 11:19 target/lib/libbrotlienc.a
ls target/include/brotli/
decode.h encode.h port.h types.h
将静态库和include里面的.h文件拷贝出来,就可以用来编译自己的程序了,也可以移植到自己的程序中,比如网上资料最多的 nginx。 我工作用的是squid,也是通过这种方式支持的
gcc -g -o test_brotli test_brotli.c -I../target/brotli/include ../target/lib/libbrotlienc.a -lm
# test_brotli.c, 程序设计其实有问题,不过这里贴出来只是作为给大家编译用的测试demo
#include "brotli/encode.h"
#include "brotli/decode.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int
test_brotli_compress()
{
int is_ok = 1;
BrotliEncoderState* s = BrotliEncoderCreateInstance(NULL, NULL, NULL);
if (!s) {
fprintf(stderr, "out of memory\n");
return 0;
}
int quality = 1;
int lgwin = 22;
BrotliEncoderSetParameter(s, BROTLI_PARAM_QUALITY, quality);
BrotliEncoderSetParameter(s, BROTLI_PARAM_LGWIN, lgwin);
uint8_t* input_buf = (uint8_t*)malloc(1024);
uint8_t* out_buf = (uint8_t*)malloc(4096);
size_t available_in = 0; /* length of real data */
size_t available_out = 1024; /* length of buf befor call compress, and length of remain size of buf after compress */
const uint8_t* next_in = NULL; /* start of in buff */
uint8_t* next_out = NULL; /* start of out buff */
strcpy((char *)input_buf, "abcdefghijklmnopqrstuvwxyz");
next_in = input_buf; /* actually data must be binary data */
available_in = strlen("abcdefghijklmnopqrstuvwxyz");
available_out = 1024;
next_out = out_buf;
if (!BrotliEncoderCompressStream(s, BROTLI_OPERATION_PROCESS, &available_in, &next_in, &available_out, &next_out, NULL)) {
/* Should detect OOM? */
fprintf(stderr, "failed to compress data [%s]\n", "abcdefghijklmnopqrstuvwxyz");
is_ok = 0;
goto failed;
}
next_in = NULL;
available_in = 0;
if (available_out != 1024) {
next_out = out_buf + (1024 - available_out); /* buf + out_size */
available_out = 1024;
}
if (!BrotliEncoderCompressStream(s, BROTLI_OPERATION_FINISH, &available_in, &next_in, &available_out, &next_out, NULL)) {
/* Should detect OOM? */
fprintf(stderr, "failed to compress data [%s]\n", "0123456789");
is_ok = 0;
goto failed;
}
if (BrotliEncoderIsFinished(s)) is_ok = 1;
BrotliEncoderDestroyInstance(s);
failed:
free(input_buf);
free(input_buf2);
free(out_buf);
return is_ok;
}
int main()
{
test_brotli_compress();
return 0;
}
1.5. 写在最后
如果大家觉有用,可以留言。后续可能会再补充在支持过程中遇到的其他问题
更新时间: 2019.08.16
网友评论