stm32 zip gz zlib研究並移植

今天,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()函數,但是我認爲把「」文件映射到內存「」,這操作不夠通用, 所以我就沒有使用,