compr_zlib.c

Joakim Tjernlund Joakim.Tjernlund at lumentis.se
Tue Mar 19 07:03:17 EST 2002


No comments so far.
Anyone?

      Jocke

On Monday 11 March 2002 09.56, Joakim Tjernlund wrote:
> Hi all
>
> I noticed that zlib.c by default adds a small header and a adler32 checksum
> to the compressed data. This is not needed since JFFS2 adds it's own CRC32.
> There is an 'undocumented' way to avoid the header and adler32 checksum,
> specify a negative windowBits to deflateInit2()/inflateInit2(). Also it is
> possible to trim the memory usage by adjusting  windowBits and memLevel
> accordinly. I have left these at their default values since I don't know
> zlib very well. Perhaps someone else can comment?
>
> Also I wonder about STREAM_END_SPACE, which is defined to 12. Is it useful
> to try and compress data as small as 13 bytes with zlib? Maybe the simpler
> rtime should be used for small amounts of data?
>
> Below is a patch against the stable 2.4 branch, which is backwards
> compatible.
>
>         Jocke
>
> PS.
>      There has been a few improvements to JFFS2 that I would like to see in
> the stable 2.4 branch, we have been using these for about 2 weeks now and I
> think they are stable.
>
>
> Index: fs/jffs2/compr_zlib.c
> ===================================================================
> RCS file: /home/cvs/mtd/fs/jffs2/compr_zlib.c,v
> retrieving revision 1.8
> diff -u -r1.8 compr_zlib.c
> --- fs/jffs2/compr_zlib.c       2001/09/20 15:28:31     1.8
> +++ fs/jffs2/compr_zlib.c       2002/03/11 08:31:35
> @@ -31,7 +31,7 @@
>   * provisions above, a recipient may use your version of this file
>   * under either the RHEPL or the GPL.
>   *
> - * $Id: compr_zlib.c,v 1.8 2001/09/20 15:28:31 dwmw2 Exp $
> + * $Id: compr_zlib.c,v 1.8 2002/01/31 13:56:11 jocke Exp $
>   *
>   */
>
> @@ -92,9 +92,21 @@
>         strm.zalloc = (void *)0;
>         strm.zfree = (void *)0;
>  #endif
> -
> -       if (Z_OK != deflateInit(&strm, 3)) {
> -               printk(KERN_WARNING "deflateInit failed\n");
> +       /* The memory requirements for deflate are (in bytes):
> +          1 << (windowBits+2)   +  1 << (memLevel+9)
> +          that is: 128K for windowBits=15  +  128K for memLevel = 8 
> (default values) +          plus a few kilobytes for small objects. For
> example, if you want to reduce +          the default memory requirements
> from 256K to 128K, compile with +              make CFLAGS="-O
> -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
> +          Of course this will generally degrade compression (there's no
> free lunch). +
> +          The memory requirements for inflate are (in bytes) 1 <<
> windowBits +          that is, 32K for windowBits=15 (default value) plus a
> few kilobytes +          for small objects.
> +       */
> +       /* -MAX_WBITS impiles -> suppress zlib header and adler32 */
> +       if (Z_OK != deflateInit2(&strm, 3, Z_DEFLATED, -MAX_WBITS, 8,
> Z_DEFAULT_STRATEGY)) { +               printk(KERN_WARNING "deflateInit2
> failed\n");
>                 return -1;
>         }
>         strm.next_in = data_in;
> @@ -142,7 +154,7 @@
>                       __u32 srclen, __u32 destlen)
>  {
>         z_stream strm;
> -       int ret;
> +       int ret, wbits, i;
>
>  #ifdef __KERNEL__
>         strm.zalloc = zalloc;
> @@ -151,23 +163,34 @@
>         strm.zalloc = (void *)0;
>         strm.zfree = (void *)0;
>  #endif
> -
> -       if (Z_OK != inflateInit(&strm)) {
> -               printk(KERN_WARNING "inflateInit failed\n");
> -               return;
> -       }
> -       strm.next_in = data_in;
> -       strm.avail_in = srclen;
> -       strm.total_in = 0;
> -
> -       strm.next_out = cpage_out;
> -       strm.avail_out = destlen;
> -       strm.total_out = 0;
> +       /* -MAX_WBITS impiles -> suppress zlib header and adler32.
> +          try first with -MAX_WBITS, if that fails, try MAX_WBITS to be
> +          backwards compatible */
> +       wbits = -MAX_WBITS;
> +       for(i = 0; i < 2; i++){
> +               if (Z_OK != inflateInit2(&strm, wbits)) {
> +                       printk(KERN_WARNING "inflateInit2 failed\n");
> +                       return;
> +               }
> +               strm.next_in = data_in;
> +               strm.avail_in = srclen;
> +               strm.total_in = 0;
> +
> +               strm.next_out = cpage_out;
> +               strm.avail_out = destlen;
> +               strm.total_out = 0;
> +
> +               while((ret = inflate(&strm, Z_FINISH)) == Z_OK)
> +                       ;
> +               inflateEnd(&strm);
> +               if (ret == Z_DATA_ERROR){
> +                       wbits = -wbits;
> +                       continue; /* try again with next wbits */
> +               }
>
> -       while((ret = inflate(&strm, Z_FINISH)) == Z_OK)
> -               ;
> -       if (ret != Z_STREAM_END) {
> -               printk(KERN_NOTICE "inflate returned %d\n", ret);
> +               if (ret != Z_STREAM_END) {
> +                       printk(KERN_NOTICE "inflate returned %d, wbits:
> %d\n", ret, wbits); +               }
> +               break; /* all went well */
>         }
> -       inflateEnd(&strm);
>  }




More information about the linux-mtd mailing list