今天,zlib是一種事實上的業界標準,以至於在標準文檔中,zlib和DEFLATE常常互換使用。數以千計的應用程序直接或間接依靠zlib壓縮函式庫,包括:
* Linux核心:使用zlib以實作網絡協定的壓縮、檔案系統的壓縮以及開機時解壓縮自身的核心。
* libpng,用於PNG圖形格式的一個實現,對bitmap數據規定了DEFLATE作爲流壓縮方法。
zlib庫已經有人移植到RTT上了,並作爲RTT的一個組件在可以在建工程的時候添加進去,我的硬件平臺是STM32F437II,那個組件僅僅是移植了zlib庫,並提供了一個例程,zlib_sample.c,這個例程很重要,我移植gzip zip的時候就是參考這個例程的,裏面月很多系統調用,比如fopen(), 在RTT下沒有,這是在stdio.h中聲明的一個函數,但函數定義找不到,最終與RTT的接口在哪我也不知道,但是可以確實的是在RTT下此函數可以用, 還有很多類似的問題。
估計這個程序初衷就不是讓單片機用的,裏面充斥的大量的系統定義,類似
#if (!defined(_WIN32)) && (!defined(WIN32)) && (!defined(__APPLE__))
#if defined(USE_FILE32API)
#define fopen64 fopen
#define ftello64 ftell
#define fseeko64 fseek
#else
#ifdef __FreeBSD__
#define fopen64 fopen
#define ftello64 ftello
#define fseeko64 fseeko
#endif
我的處理就是順其自然,首先那個「」WIN「」定義肯定是不能用的,然後再在其它選項中找,比如上面的定義,我就在KEIL中定義了USE_FILE32API,因爲fopen fseek都能找到。
還有一個 fileno(file) 定義,我實在找不到RTT中對應的相關定義,經過查看,這個地方用在標準輸入輸出,stdin stdout,可以不用,我們的壓縮解壓縮輸入輸出都是文件格式,並不是標準輸入輸出接口,於是把相關引用的地方都屏蔽掉就行了,
經過一翻折騰折騰,終於可以編譯通過了。編譯通過只是開始,下面要就要研究gzip zip的命令了,這2種壓縮格式都是使用的zlib庫,並且都使用的命令行工作模式,
gzip 主要就是調用file_compress(*argv, outmode); 函數。
file_compress("/NOR/log.txt", "wb9f");
/* ===========================================================================
* Usage: minigzip [-c] [-d] [-f] [-h] [-r] [-1 to -9] [files...]
* -c : write to standard output
* -d : decompress
* -f : compress with Z_FILTERED
* -h : compress with Z_HUFFMAN_ONLY
* -r : compress with Z_RLE
* -1 to -9 : compression level
*/
順便說一下,-f是 Z_FILTERED方式,壓縮率很高,我剛開始使用Z_HUFFMAN_ONLY,無論使用1,還是9,壓縮率都提不上,後來選擇 Z_FILTERED之後,壓縮率一下就提上去了。
zip我只移植了miniunz命令,這個參數太多了,我測試了很九才弄明白, 它可以分爲
1.只把壓縮包中的文件名、類型、日期等信息列出來。
2.解壓縮所有文件。
3.解壓縮其中1個文件。
printf("MiniUnz 1.01b, demo of zLib + Unz package written by Gilles Vollant\n");
printf("more info at http://www.winimage.com/zLibDll/unzip.html\n\n");
printf("Usage : miniunz [-e] [-x] [-v] [-l] [-o] [-p password] file.zip [file_to_extr.] [-d extractdir]\n\n" \
" -e Extract without pathname (junk paths)\n" \
" -x Extract with pathname\n" \
" -v list files\n" \
" -l list files\n" \
" -d directory to extract into\n" \
" -o overwrite files without prompting\n" \
" -p extract crypted file using password\n\n");
使用的的過程中,使用絕對路徑不方便,還好RTT也支持相對路徑, chdir()就可以了。
移植的過程中我最大的感受是RTT提供了非常完善的系統調用,只有你想不到的,沒有它提供不了的。
有一個
#ifdef USE_MMAP
int gz_compress_mmap OF((FILE *in, gzFile out));
#endif
居然RTT還提供了mmap()函數,但是我認爲把「」文件映射到內存「」,這操作不夠通用, 所以我就沒有使用,