uboot/fs/jffs2/compr_rubin.c
<<
>>
Prefs
   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 * Heavily modified by Russ Dill <Russ.Dill@asu.edu> in an attempt at
   9 * a little more speed.
  10 *
  11 * The original JFFS, from which the design for JFFS2 was derived,
  12 * was designed and implemented by Axis Communications AB.
  13 *
  14 * The contents of this file are subject to the Red Hat eCos Public
  15 * License Version 1.1 (the "Licence"); you may not use this file
  16 * except in compliance with the Licence.  You may obtain a copy of
  17 * the Licence at http://www.redhat.com/
  18 *
  19 * Software distributed under the Licence is distributed on an "AS IS"
  20 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
  21 * See the Licence for the specific language governing rights and
  22 * limitations under the Licence.
  23 *
  24 * The Original Code is JFFS2 - Journalling Flash File System, version 2
  25 *
  26 * Alternatively, the contents of this file may be used under the
  27 * terms of the GNU General Public License version 2 (the "GPL"), in
  28 * which case the provisions of the GPL are applicable instead of the
  29 * above.  If you wish to allow the use of your version of this file
  30 * only under the terms of the GPL and not to allow others to use your
  31 * version of this file under the RHEPL, indicate your decision by
  32 * deleting the provisions above and replace them with the notice and
  33 * other provisions required by the GPL.  If you do not delete the
  34 * provisions above, a recipient may use your version of this file
  35 * under either the RHEPL or the GPL.
  36 *
  37 * $Id: compr_rubin.c,v 1.2 2002/01/24 22:58:42 rfeany Exp $
  38 *
  39 */
  40
  41#include <config.h>
  42#include <jffs2/jffs2.h>
  43#include <jffs2/compr_rubin.h>
  44
  45
  46void rubin_do_decompress(unsigned char *bits, unsigned char *in,
  47                         unsigned char *page_out, __u32 destlen)
  48{
  49        register char *curr = (char *)page_out;
  50        char *end = (char *)(page_out + destlen);
  51        register unsigned long temp;
  52        register unsigned long result;
  53        register unsigned long p;
  54        register unsigned long q;
  55        register unsigned long rec_q;
  56        register unsigned long bit;
  57        register long i0;
  58        unsigned long i;
  59
  60        /* init_pushpull */
  61        temp = *(u32 *) in;
  62        bit = 16;
  63
  64        /* init_rubin */
  65        q = 0;
  66        p = (long) (2 * UPPER_BIT_RUBIN);
  67
  68        /* init_decode */
  69        rec_q = (in[0] << 8) | in[1];
  70
  71        while (curr < end) {
  72                /* in byte */
  73
  74                result = 0;
  75                for (i = 0; i < 8; i++) {
  76                        /* decode */
  77
  78                        while ((q & UPPER_BIT_RUBIN) || ((p + q) <= UPPER_BIT_RUBIN)) {
  79                                q &= ~UPPER_BIT_RUBIN;
  80                                q <<= 1;
  81                                p <<= 1;
  82                                rec_q &= ~UPPER_BIT_RUBIN;
  83                                rec_q <<= 1;
  84                                rec_q |= (temp >> (bit++ ^ 7)) & 1;
  85                                if (bit > 31) {
  86                                        u32 *p = (u32 *)in;
  87                                        bit = 0;
  88                                        temp = *(++p);
  89                                        in = (unsigned char *)p;
  90                                }
  91                        }
  92                        i0 =  (bits[i] * p) >> 8;
  93
  94                        if (i0 <= 0) i0 = 1;
  95                        /* if it fails, it fails, we have our crc
  96                        if (i0 >= p) i0 = p - 1; */
  97
  98                        result >>= 1;
  99                        if (rec_q < q + i0) {
 100                                /* result |= 0x00; */
 101                                p = i0;
 102                        } else {
 103                                result |= 0x80;
 104                                p -= i0;
 105                                q += i0;
 106                        }
 107                }
 108                *(curr++) = result;
 109        }
 110}
 111
 112void dynrubin_decompress(unsigned char *data_in, unsigned char *cpage_out,
 113                   unsigned long sourcelen, unsigned long dstlen)
 114{
 115        unsigned char bits[8];
 116        int c;
 117
 118        for (c=0; c<8; c++)
 119                bits[c] = (256 - data_in[c]);
 120
 121        rubin_do_decompress(bits, data_in+8, cpage_out, dstlen);
 122}
 123