compr_zlib.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:5k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  * JFFS2 -- Journalling Flash File System, Version 2.
  3.  *
  4.  * Copyright (C) 2001 Red Hat, Inc.
  5.  *
  6.  * Created by David Woodhouse <dwmw2@cambridge.redhat.com>
  7.  *
  8.  * The original JFFS, from which the design for JFFS2 was derived,
  9.  * was designed and implemented by Axis Communications AB.
  10.  *
  11.  * The contents of this file are subject to the Red Hat eCos Public
  12.  * License Version 1.1 (the "Licence"); you may not use this file
  13.  * except in compliance with the Licence.  You may obtain a copy of
  14.  * the Licence at http://www.redhat.com/
  15.  *
  16.  * Software distributed under the Licence is distributed on an "AS IS"
  17.  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
  18.  * See the Licence for the specific language governing rights and
  19.  * limitations under the Licence.
  20.  *
  21.  * The Original Code is JFFS2 - Journalling Flash File System, version 2
  22.  *
  23.  * Alternatively, the contents of this file may be used under the
  24.  * terms of the GNU General Public License version 2 (the "GPL"), in
  25.  * which case the provisions of the GPL are applicable instead of the
  26.  * above.  If you wish to allow the use of your version of this file
  27.  * only under the terms of the GPL and not to allow others to use your
  28.  * version of this file under the RHEPL, indicate your decision by
  29.  * deleting the provisions above and replace them with the notice and
  30.  * other provisions required by the GPL.  If you do not delete the
  31.  * provisions above, a recipient may use your version of this file
  32.  * under either the RHEPL or the GPL.
  33.  *
  34.  * $Id: compr_zlib.c,v 1.8 2001/09/20 15:28:31 dwmw2 Exp $
  35.  *
  36.  */
  37. #include "zlib.h"
  38. #ifdef __KERNEL__
  39. #include <linux/kernel.h>
  40. #include <linux/mtd/compatmac.h> /* for min() */
  41. #include <linux/slab.h>
  42. #include <linux/jffs2.h>
  43. #include "nodelist.h"
  44. static void *zalloc(void *opaque, unsigned nr, unsigned size)
  45. {
  46. /* How much does it request? Should we use vmalloc? Or be dynamic? */
  47. return kmalloc(nr * size, GFP_KERNEL);
  48. }
  49. static void zfree(void *opaque, void *addr)
  50. {
  51. kfree(addr);
  52. }
  53. #else
  54. #define min(x,y) ((x)<(y)?(x):(y))
  55. #ifndef D1
  56. #define D1(x)
  57. #endif
  58. #define KERN_DEBUG
  59. #define KERN_NOTICE
  60. #define KERN_WARNING
  61. #define printk printf
  62. #include <stdio.h>
  63. #include <asm/types.h>
  64. #endif
  65. /* Plan: call deflate() with avail_in == *sourcelen, 
  66. avail_out = *dstlen - 12 and flush == Z_FINISH. 
  67. If it doesn't manage to finish, call it again with
  68. avail_in == 0 and avail_out set to the remaining 12
  69. bytes for it to clean up. 
  70.    Q: Is 12 bytes sufficient?
  71. */
  72. #define STREAM_END_SPACE 12
  73. int zlib_compress(unsigned char *data_in, unsigned char *cpage_out, 
  74.    __u32 *sourcelen, __u32 *dstlen)
  75. {
  76. z_stream strm;
  77. int ret;
  78. if (*dstlen <= STREAM_END_SPACE)
  79. return -1;
  80. #ifdef __KERNEL__
  81. strm.zalloc = zalloc;
  82. strm.zfree = zfree;
  83. #else
  84. strm.zalloc = (void *)0;
  85. strm.zfree = (void *)0;
  86. #endif
  87. if (Z_OK != deflateInit(&strm, 3)) {
  88. printk(KERN_WARNING "deflateInit failedn");
  89. return -1;
  90. }
  91. strm.next_in = data_in;
  92. strm.total_in = 0;
  93. strm.next_out = cpage_out;
  94. strm.total_out = 0;
  95. while (strm.total_out < *dstlen - STREAM_END_SPACE && strm.total_in < *sourcelen) {
  96. strm.avail_out = *dstlen - (strm.total_out + STREAM_END_SPACE);
  97. strm.avail_in = min((unsigned)(*sourcelen-strm.total_in), strm.avail_out);
  98. D1(printk(KERN_DEBUG "calling deflate with avail_in %d, avail_out %dn",
  99.   strm.avail_in, strm.avail_out));
  100. ret = deflate(&strm, Z_PARTIAL_FLUSH);
  101. D1(printk(KERN_DEBUG "deflate returned with avail_in %d, avail_out %d, total_in %ld, total_out %ldn", 
  102.   strm.avail_in, strm.avail_out, strm.total_in, strm.total_out));
  103. if (ret != Z_OK) {
  104. D1(printk(KERN_DEBUG "deflate in loop returned %dn", ret));
  105. deflateEnd(&strm);
  106. return -1;
  107. }
  108. }
  109. strm.avail_out += STREAM_END_SPACE;
  110. strm.avail_in = 0;
  111. ret = deflate(&strm, Z_FINISH);
  112. if (ret != Z_STREAM_END) {
  113. D1(printk(KERN_DEBUG "final deflate returned %dn", ret));
  114. deflateEnd(&strm);
  115. return -1;
  116. }
  117. deflateEnd(&strm);
  118. D1(printk(KERN_DEBUG "zlib compressed %ld bytes into %ldn", strm.total_in, strm.total_out));
  119. if (strm.total_out >= strm.total_in)
  120. return -1;
  121. *dstlen = strm.total_out;
  122. *sourcelen = strm.total_in;
  123. return 0;
  124. }
  125. void zlib_decompress(unsigned char *data_in, unsigned char *cpage_out,
  126.       __u32 srclen, __u32 destlen)
  127. {
  128. z_stream strm;
  129. int ret;
  130. #ifdef __KERNEL__
  131. strm.zalloc = zalloc;
  132. strm.zfree = zfree;
  133. #else
  134. strm.zalloc = (void *)0;
  135. strm.zfree = (void *)0;
  136. #endif
  137. if (Z_OK != inflateInit(&strm)) {
  138. printk(KERN_WARNING "inflateInit failedn");
  139. return;
  140. }
  141. strm.next_in = data_in;
  142. strm.avail_in = srclen;
  143. strm.total_in = 0;
  144. strm.next_out = cpage_out;
  145. strm.avail_out = destlen;
  146. strm.total_out = 0;
  147. while((ret = inflate(&strm, Z_FINISH)) == Z_OK)
  148. ;
  149. if (ret != Z_STREAM_END) {
  150. printk(KERN_NOTICE "inflate returned %dn", ret);
  151. }
  152. inflateEnd(&strm);
  153. }