compr_rubin.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:7k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  * JFFS2 -- Journalling Flash File System, Version 2.
  3.  *
  4.  * Copyright (C) 2001 Red Hat, Inc.
  5.  *
  6.  * Created by Arjan van de Ven <arjanv@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_rubin.c,v 1.13 2001/09/23 10:06:05 rmk Exp $
  35.  *
  36.  */
  37.  
  38. #include <linux/string.h>
  39. #include <linux/types.h>
  40. #include "compr_rubin.h"
  41. #include "histo_mips.h"
  42. void init_rubin(struct rubin_state *rs, int div, int *bits)
  43. {
  44. int c;
  45. rs->q = 0;
  46. rs->p = (long) (2 * UPPER_BIT_RUBIN);
  47. rs->bit_number = (long) 0;
  48. rs->bit_divider = div;
  49. for (c=0; c<8; c++)
  50. rs->bits[c] = bits[c];
  51. }
  52. int encode(struct rubin_state *rs, long A, long B, int symbol)
  53. {
  54. long i0, i1;
  55. int ret;
  56. while ((rs->q >= UPPER_BIT_RUBIN) || ((rs->p + rs->q) <= UPPER_BIT_RUBIN)) {
  57. rs->bit_number++;
  58. ret = pushbit(&rs->pp, (rs->q & UPPER_BIT_RUBIN) ? 1 : 0, 0);
  59. if (ret)
  60. return ret;
  61. rs->q &= LOWER_BITS_RUBIN;
  62. rs->q <<= 1;
  63. rs->p <<= 1;
  64. }
  65. i0 = A * rs->p / (A + B);
  66. if (i0 <= 0) {
  67. i0 = 1;
  68. }
  69. if (i0 >= rs->p) {
  70. i0 = rs->p - 1;
  71. }
  72. i1 = rs->p - i0;
  73. if (symbol == 0)
  74. rs->p = i0;
  75. else {
  76. rs->p = i1;
  77. rs->q += i0;
  78. }
  79. return 0;
  80. }
  81. void end_rubin(struct rubin_state *rs)
  82. {
  83. int i;
  84. for (i = 0; i < RUBIN_REG_SIZE; i++) {
  85. pushbit(&rs->pp, (UPPER_BIT_RUBIN & rs->q) ? 1 : 0, 1);
  86. rs->q &= LOWER_BITS_RUBIN;
  87. rs->q <<= 1;
  88. }
  89. }
  90. void init_decode(struct rubin_state *rs, int div, int *bits)
  91. {
  92. init_rubin(rs, div, bits);
  93. /* behalve lower */
  94. rs->rec_q = 0;
  95. for (rs->bit_number = 0; rs->bit_number++ < RUBIN_REG_SIZE; rs->rec_q = rs->rec_q * 2 + (long) (pullbit(&rs->pp)))
  96. ;
  97. }
  98. static void __do_decode(struct rubin_state *rs, unsigned long p, unsigned long q)
  99. {
  100. register unsigned long lower_bits_rubin = LOWER_BITS_RUBIN;
  101. unsigned long rec_q;
  102. int c, bits = 0;
  103. /*
  104.  * First, work out how many bits we need from the input stream.
  105.  * Note that we have already done the initial check on this
  106.  * loop prior to calling this function.
  107.  */
  108. do {
  109. bits++;
  110. q &= lower_bits_rubin;
  111. q <<= 1;
  112. p <<= 1;
  113. } while ((q >= UPPER_BIT_RUBIN) || ((p + q) <= UPPER_BIT_RUBIN));
  114. rs->p = p;
  115. rs->q = q;
  116. rs->bit_number += bits;
  117. /*
  118.  * Now get the bits.  We really want this to be "get n bits".
  119.  */
  120. rec_q = rs->rec_q;
  121. do {
  122. c = pullbit(&rs->pp);
  123. rec_q &= lower_bits_rubin;
  124. rec_q <<= 1;
  125. rec_q += c;
  126. } while (--bits);
  127. rs->rec_q = rec_q;
  128. }
  129. int decode(struct rubin_state *rs, long A, long B)
  130. {
  131. unsigned long p = rs->p, q = rs->q;
  132. long i0, threshold;
  133. int symbol;
  134. if (q >= UPPER_BIT_RUBIN || ((p + q) <= UPPER_BIT_RUBIN))
  135. __do_decode(rs, p, q);
  136. i0 = A * rs->p / (A + B);
  137. if (i0 <= 0) {
  138. i0 = 1;
  139. }
  140. if (i0 >= rs->p) {
  141. i0 = rs->p - 1;
  142. }
  143. threshold = rs->q + i0;
  144. symbol = rs->rec_q >= threshold;
  145. if (rs->rec_q >= threshold) {
  146. rs->q += i0;
  147. i0 = rs->p - i0;
  148. }
  149. rs->p = i0;
  150. return symbol;
  151. }
  152. static int out_byte(struct rubin_state *rs, unsigned char byte)
  153. {
  154. int i, ret;
  155. struct rubin_state rs_copy;
  156. rs_copy = *rs;
  157. for (i=0;i<8;i++) {
  158. ret = encode(rs, rs->bit_divider-rs->bits[i],rs->bits[i],byte&1);
  159. if (ret) {
  160. /* Failed. Restore old state */
  161. *rs = rs_copy;
  162. return ret;
  163. }
  164. byte=byte>>1;
  165. }
  166. return 0;
  167. }
  168. static int in_byte(struct rubin_state *rs)
  169. {
  170. int i, result = 0, bit_divider = rs->bit_divider;
  171. for (i = 0; i < 8; i++)
  172. result |= decode(rs, bit_divider - rs->bits[i], rs->bits[i]) << i;
  173. return result;
  174. }
  175. int rubin_do_compress(int bit_divider, int *bits, unsigned char *data_in, 
  176.       unsigned char *cpage_out, __u32 *sourcelen, __u32 *dstlen)
  177. {
  178. int outpos = 0;
  179. int pos=0;
  180. struct rubin_state rs;
  181. init_pushpull(&rs.pp, cpage_out, *dstlen * 8, 0, 32);
  182. init_rubin(&rs, bit_divider, bits);
  183. while (pos < (*sourcelen) && !out_byte(&rs, data_in[pos]))
  184. pos++;
  185. end_rubin(&rs);
  186. if (outpos > pos) {
  187. /* We failed */
  188. return -1;
  189. }
  190. /* Tell the caller how much we managed to compress, 
  191.  * and how much space it took */
  192. outpos = (pushedbits(&rs.pp)+7)/8;
  193. if (outpos >= pos)
  194. return -1; /* We didn't actually compress */
  195. *sourcelen = pos;
  196. *dstlen = outpos;
  197. return 0;
  198. }    
  199. #if 0
  200. /* _compress returns the compressed size, -1 if bigger */
  201. int rubinmips_compress(unsigned char *data_in, unsigned char *cpage_out, 
  202.    __u32 *sourcelen, __u32 *dstlen)
  203. {
  204. return rubin_do_compress(BIT_DIVIDER_MIPS, bits_mips, data_in, cpage_out, sourcelen, dstlen);
  205. }
  206. #endif
  207. int dynrubin_compress(unsigned char *data_in, unsigned char *cpage_out, 
  208.    __u32 *sourcelen, __u32 *dstlen)
  209. {
  210. int bits[8];
  211. unsigned char histo[256];
  212. int i;
  213. int ret;
  214. __u32 mysrclen, mydstlen;
  215. mysrclen = *sourcelen;
  216. mydstlen = *dstlen - 8;
  217. if (*dstlen <= 12)
  218. return -1;
  219. memset(histo, 0, 256);
  220. for (i=0; i<mysrclen; i++) {
  221. histo[data_in[i]]++;
  222. }
  223. memset(bits, 0, sizeof(int)*8);
  224. for (i=0; i<256; i++) {
  225. if (i&128)
  226. bits[7] += histo[i];
  227. if (i&64)
  228. bits[6] += histo[i];
  229. if (i&32)
  230. bits[5] += histo[i];
  231. if (i&16)
  232. bits[4] += histo[i];
  233. if (i&8)
  234. bits[3] += histo[i];
  235. if (i&4)
  236. bits[2] += histo[i];
  237. if (i&2)
  238. bits[1] += histo[i];
  239. if (i&1)
  240. bits[0] += histo[i];
  241. }
  242. for (i=0; i<8; i++) {
  243. bits[i] = (bits[i] * 256) / mysrclen;
  244. if (!bits[i]) bits[i] = 1;
  245. if (bits[i] > 255) bits[i] = 255;
  246. cpage_out[i] = bits[i];
  247. }
  248. ret = rubin_do_compress(256, bits, data_in, cpage_out+8, &mysrclen, &mydstlen);
  249. if (ret) 
  250. return ret;
  251. /* Add back the 8 bytes we took for the probabilities */
  252. mydstlen += 8;
  253. if (mysrclen <= mydstlen) {
  254. /* We compressed */
  255. return -1;
  256. }
  257. *sourcelen = mysrclen;
  258. *dstlen = mydstlen;
  259. return 0;
  260. }
  261. void rubin_do_decompress(int bit_divider, int *bits, unsigned char *cdata_in, 
  262.  unsigned char *page_out, __u32 srclen, __u32 destlen)
  263. {
  264. int outpos = 0;
  265. struct rubin_state rs;
  266. init_pushpull(&rs.pp, cdata_in, srclen, 0, 0);
  267. init_decode(&rs, bit_divider, bits);
  268. while (outpos < destlen) {
  269. page_out[outpos++] = in_byte(&rs);
  270. }
  271. }    
  272. void rubinmips_decompress(unsigned char *data_in, unsigned char *cpage_out, 
  273.    __u32 sourcelen, __u32 dstlen)
  274. {
  275. rubin_do_decompress(BIT_DIVIDER_MIPS, bits_mips, data_in, cpage_out, sourcelen, dstlen);
  276. }
  277. void dynrubin_decompress(unsigned char *data_in, unsigned char *cpage_out, 
  278.    __u32 sourcelen, __u32 dstlen)
  279. {
  280. int bits[8];
  281. int c;
  282. for (c=0; c<8; c++)
  283. bits[c] = data_in[c];
  284. rubin_do_decompress(256, bits, data_in+8, cpage_out, sourcelen-8, dstlen);
  285. }