linux/fs/jffs2/compr_rubin.c
<<
>>
Prefs
   1/*
   2 * JFFS2 -- Journalling Flash File System, Version 2.
   3 *
   4 * Copyright © 2001-2007 Red Hat, Inc.
   5 * Copyright © 2004-2010 David Woodhouse <dwmw2@infradead.org>
   6 *
   7 * Created by Arjan van de Ven <arjanv@redhat.com>
   8 *
   9 * For licensing information, see the file 'LICENCE' in this directory.
  10 *
  11 */
  12
  13#include <linux/string.h>
  14#include <linux/types.h>
  15#include <linux/jffs2.h>
  16#include <linux/errno.h>
  17#include "compr.h"
  18
  19
  20#define RUBIN_REG_SIZE   16
  21#define UPPER_BIT_RUBIN    (((long) 1)<<(RUBIN_REG_SIZE-1))
  22#define LOWER_BITS_RUBIN   ((((long) 1)<<(RUBIN_REG_SIZE-1))-1)
  23
  24
  25#define BIT_DIVIDER_MIPS 1043
  26static int bits_mips[8] = { 277, 249, 290, 267, 229, 341, 212, 241};
  27
  28struct pushpull {
  29        unsigned char *buf;
  30        unsigned int buflen;
  31        unsigned int ofs;
  32        unsigned int reserve;
  33};
  34
  35struct rubin_state {
  36        unsigned long p;
  37        unsigned long q;
  38        unsigned long rec_q;
  39        long bit_number;
  40        struct pushpull pp;
  41        int bit_divider;
  42        int bits[8];
  43};
  44
  45static inline void init_pushpull(struct pushpull *pp, char *buf,
  46                                 unsigned buflen, unsigned ofs,
  47                                 unsigned reserve)
  48{
  49        pp->buf = buf;
  50        pp->buflen = buflen;
  51        pp->ofs = ofs;
  52        pp->reserve = reserve;
  53}
  54
  55static inline int pushbit(struct pushpull *pp, int bit, int use_reserved)
  56{
  57        if (pp->ofs >= pp->buflen - (use_reserved?0:pp->reserve))
  58                return -ENOSPC;
  59
  60        if (bit)
  61                pp->buf[pp->ofs >> 3] |= (1<<(7-(pp->ofs & 7)));
  62        else
  63                pp->buf[pp->ofs >> 3] &= ~(1<<(7-(pp->ofs & 7)));
  64
  65        pp->ofs++;
  66
  67        return 0;
  68}
  69
  70static inline int pushedbits(struct pushpull *pp)
  71{
  72        return pp->ofs;
  73}
  74
  75static inline int pullbit(struct pushpull *pp)
  76{
  77        int bit;
  78
  79        bit = (pp->buf[pp->ofs >> 3] >> (7-(pp->ofs & 7))) & 1;
  80
  81        pp->ofs++;
  82        return bit;
  83}
  84
  85static inline int pulledbits(struct pushpull *pp)
  86{
  87        return pp->ofs;
  88}
  89
  90
  91static void init_rubin(struct rubin_state *rs, int div, int *bits)
  92{
  93        int c;
  94
  95        rs->q = 0;
  96        rs->p = (long) (2 * UPPER_BIT_RUBIN);
  97        rs->bit_number = (long) 0;
  98        rs->bit_divider = div;
  99
 100        for (c=0; c<8; c++)
 101                rs->bits[c] = bits[c];
 102}
 103
 104
 105static int encode(struct rubin_state *rs, long A, long B, int symbol)
 106{
 107
 108        long i0, i1;
 109        int ret;
 110
 111        while ((rs->q >= UPPER_BIT_RUBIN) ||
 112               ((rs->p + rs->q) <= UPPER_BIT_RUBIN)) {
 113                rs->bit_number++;
 114
 115                ret = pushbit(&rs->pp, (rs->q & UPPER_BIT_RUBIN) ? 1 : 0, 0);
 116                if (ret)
 117                        return ret;
 118                rs->q &= LOWER_BITS_RUBIN;
 119                rs->q <<= 1;
 120                rs->p <<= 1;
 121        }
 122        i0 = A * rs->p / (A + B);
 123        if (i0 <= 0)
 124                i0 = 1;
 125
 126        if (i0 >= rs->p)
 127                i0 = rs->p - 1;
 128
 129        i1 = rs->p - i0;
 130
 131        if (symbol == 0)
 132                rs->p = i0;
 133        else {
 134                rs->p = i1;
 135                rs->q += i0;
 136        }
 137        return 0;
 138}
 139
 140
 141static void end_rubin(struct rubin_state *rs)
 142{
 143
 144        int i;
 145
 146        for (i = 0; i < RUBIN_REG_SIZE; i++) {
 147                pushbit(&rs->pp, (UPPER_BIT_RUBIN & rs->q) ? 1 : 0, 1);
 148                rs->q &= LOWER_BITS_RUBIN;
 149                rs->q <<= 1;
 150        }
 151}
 152
 153
 154static void init_decode(struct rubin_state *rs, int div, int *bits)
 155{
 156        init_rubin(rs, div, bits);
 157
 158        /* behalve lower */
 159        rs->rec_q = 0;
 160
 161        for (rs->bit_number = 0; rs->bit_number++ < RUBIN_REG_SIZE;
 162             rs->rec_q = rs->rec_q * 2 + (long) (pullbit(&rs->pp)))
 163                ;
 164}
 165
 166static void __do_decode(struct rubin_state *rs, unsigned long p,
 167                        unsigned long q)
 168{
 169        register unsigned long lower_bits_rubin = LOWER_BITS_RUBIN;
 170        unsigned long rec_q;
 171        int c, bits = 0;
 172
 173        /*
 174         * First, work out how many bits we need from the input stream.
 175         * Note that we have already done the initial check on this
 176         * loop prior to calling this function.
 177         */
 178        do {
 179                bits++;
 180                q &= lower_bits_rubin;
 181                q <<= 1;
 182                p <<= 1;
 183        } while ((q >= UPPER_BIT_RUBIN) || ((p + q) <= UPPER_BIT_RUBIN));
 184
 185        rs->p = p;
 186        rs->q = q;
 187
 188        rs->bit_number += bits;
 189
 190        /*
 191         * Now get the bits.  We really want this to be "get n bits".
 192         */
 193        rec_q = rs->rec_q;
 194        do {
 195                c = pullbit(&rs->pp);
 196                rec_q &= lower_bits_rubin;
 197                rec_q <<= 1;
 198                rec_q += c;
 199        } while (--bits);
 200        rs->rec_q = rec_q;
 201}
 202
 203static int decode(struct rubin_state *rs, long A, long B)
 204{
 205        unsigned long p = rs->p, q = rs->q;
 206        long i0, threshold;
 207        int symbol;
 208
 209        if (q >= UPPER_BIT_RUBIN || ((p + q) <= UPPER_BIT_RUBIN))
 210                __do_decode(rs, p, q);
 211
 212        i0 = A * rs->p / (A + B);
 213        if (i0 <= 0)
 214                i0 = 1;
 215
 216        if (i0 >= rs->p)
 217                i0 = rs->p - 1;
 218
 219        threshold = rs->q + i0;
 220        symbol = rs->rec_q >= threshold;
 221        if (rs->rec_q >= threshold) {
 222                rs->q += i0;
 223                i0 = rs->p - i0;
 224        }
 225
 226        rs->p = i0;
 227
 228        return symbol;
 229}
 230
 231
 232
 233static int out_byte(struct rubin_state *rs, unsigned char byte)
 234{
 235        int i, ret;
 236        struct rubin_state rs_copy;
 237        rs_copy = *rs;
 238
 239        for (i=0; i<8; i++) {
 240                ret = encode(rs, rs->bit_divider-rs->bits[i],
 241                             rs->bits[i], byte & 1);
 242                if (ret) {
 243                        /* Failed. Restore old state */
 244                        *rs = rs_copy;
 245                        return ret;
 246                }
 247                byte >>= 1 ;
 248        }
 249        return 0;
 250}
 251
 252static int in_byte(struct rubin_state *rs)
 253{
 254        int i, result = 0, bit_divider = rs->bit_divider;
 255
 256        for (i = 0; i < 8; i++)
 257                result |= decode(rs, bit_divider - rs->bits[i],
 258                                 rs->bits[i]) << i;
 259
 260        return result;
 261}
 262
 263
 264
 265static int rubin_do_compress(int bit_divider, int *bits, unsigned char *data_in,
 266                             unsigned char *cpage_out, uint32_t *sourcelen,
 267                             uint32_t *dstlen)
 268        {
 269        int outpos = 0;
 270        int pos=0;
 271        struct rubin_state rs;
 272
 273        init_pushpull(&rs.pp, cpage_out, *dstlen * 8, 0, 32);
 274
 275        init_rubin(&rs, bit_divider, bits);
 276
 277        while (pos < (*sourcelen) && !out_byte(&rs, data_in[pos]))
 278                pos++;
 279
 280        end_rubin(&rs);
 281
 282        if (outpos > pos) {
 283                /* We failed */
 284                return -1;
 285        }
 286
 287        /* Tell the caller how much we managed to compress,
 288         * and how much space it took */
 289
 290        outpos = (pushedbits(&rs.pp)+7)/8;
 291
 292        if (outpos >= pos)
 293                return -1; /* We didn't actually compress */
 294        *sourcelen = pos;
 295        *dstlen = outpos;
 296        return 0;
 297}
 298#if 0
 299/* _compress returns the compressed size, -1 if bigger */
 300int jffs2_rubinmips_compress(unsigned char *data_in, unsigned char *cpage_out,
 301                   uint32_t *sourcelen, uint32_t *dstlen)
 302{
 303        return rubin_do_compress(BIT_DIVIDER_MIPS, bits_mips, data_in,
 304                                 cpage_out, sourcelen, dstlen);
 305}
 306#endif
 307static int jffs2_dynrubin_compress(unsigned char *data_in,
 308                                   unsigned char *cpage_out,
 309                                   uint32_t *sourcelen, uint32_t *dstlen)
 310{
 311        int bits[8];
 312        unsigned char histo[256];
 313        int i;
 314        int ret;
 315        uint32_t mysrclen, mydstlen;
 316
 317        mysrclen = *sourcelen;
 318        mydstlen = *dstlen - 8;
 319
 320        if (*dstlen <= 12)
 321                return -1;
 322
 323        memset(histo, 0, 256);
 324        for (i=0; i<mysrclen; i++)
 325                histo[data_in[i]]++;
 326        memset(bits, 0, sizeof(int)*8);
 327        for (i=0; i<256; i++) {
 328                if (i&128)
 329                        bits[7] += histo[i];
 330                if (i&64)
 331                        bits[6] += histo[i];
 332                if (i&32)
 333                        bits[5] += histo[i];
 334                if (i&16)
 335                        bits[4] += histo[i];
 336                if (i&8)
 337                        bits[3] += histo[i];
 338                if (i&4)
 339                        bits[2] += histo[i];
 340                if (i&2)
 341                        bits[1] += histo[i];
 342                if (i&1)
 343                        bits[0] += histo[i];
 344        }
 345
 346        for (i=0; i<8; i++) {
 347                bits[i] = (bits[i] * 256) / mysrclen;
 348                if (!bits[i]) bits[i] = 1;
 349                if (bits[i] > 255) bits[i] = 255;
 350                cpage_out[i] = bits[i];
 351        }
 352
 353        ret = rubin_do_compress(256, bits, data_in, cpage_out+8, &mysrclen,
 354                                &mydstlen);
 355        if (ret)
 356                return ret;
 357
 358        /* Add back the 8 bytes we took for the probabilities */
 359        mydstlen += 8;
 360
 361        if (mysrclen <= mydstlen) {
 362                /* We compressed */
 363                return -1;
 364        }
 365
 366        *sourcelen = mysrclen;
 367        *dstlen = mydstlen;
 368        return 0;
 369}
 370
 371static void rubin_do_decompress(int bit_divider, int *bits,
 372                                unsigned char *cdata_in, 
 373                                unsigned char *page_out, uint32_t srclen,
 374                                uint32_t destlen)
 375{
 376        int outpos = 0;
 377        struct rubin_state rs;
 378
 379        init_pushpull(&rs.pp, cdata_in, srclen, 0, 0);
 380        init_decode(&rs, bit_divider, bits);
 381
 382        while (outpos < destlen)
 383                page_out[outpos++] = in_byte(&rs);
 384}
 385
 386
 387static int jffs2_rubinmips_decompress(unsigned char *data_in,
 388                                      unsigned char *cpage_out,
 389                                      uint32_t sourcelen, uint32_t dstlen)
 390{
 391        rubin_do_decompress(BIT_DIVIDER_MIPS, bits_mips, data_in,
 392                            cpage_out, sourcelen, dstlen);
 393        return 0;
 394}
 395
 396static int jffs2_dynrubin_decompress(unsigned char *data_in,
 397                                     unsigned char *cpage_out,
 398                                     uint32_t sourcelen, uint32_t dstlen)
 399{
 400        int bits[8];
 401        int c;
 402
 403        for (c=0; c<8; c++)
 404                bits[c] = data_in[c];
 405
 406        rubin_do_decompress(256, bits, data_in+8, cpage_out, sourcelen-8,
 407                            dstlen);
 408        return 0;
 409}
 410
 411static struct jffs2_compressor jffs2_rubinmips_comp = {
 412        .priority = JFFS2_RUBINMIPS_PRIORITY,
 413        .name = "rubinmips",
 414        .compr = JFFS2_COMPR_DYNRUBIN,
 415        .compress = NULL, /*&jffs2_rubinmips_compress,*/
 416        .decompress = &jffs2_rubinmips_decompress,
 417#ifdef JFFS2_RUBINMIPS_DISABLED
 418        .disabled = 1,
 419#else
 420        .disabled = 0,
 421#endif
 422};
 423
 424int jffs2_rubinmips_init(void)
 425{
 426        return jffs2_register_compressor(&jffs2_rubinmips_comp);
 427}
 428
 429void jffs2_rubinmips_exit(void)
 430{
 431        jffs2_unregister_compressor(&jffs2_rubinmips_comp);
 432}
 433
 434static struct jffs2_compressor jffs2_dynrubin_comp = {
 435        .priority = JFFS2_DYNRUBIN_PRIORITY,
 436        .name = "dynrubin",
 437        .compr = JFFS2_COMPR_RUBINMIPS,
 438        .compress = jffs2_dynrubin_compress,
 439        .decompress = &jffs2_dynrubin_decompress,
 440#ifdef JFFS2_DYNRUBIN_DISABLED
 441        .disabled = 1,
 442#else
 443        .disabled = 0,
 444#endif
 445};
 446
 447int jffs2_dynrubin_init(void)
 448{
 449        return jffs2_register_compressor(&jffs2_dynrubin_comp);
 450}
 451
 452void jffs2_dynrubin_exit(void)
 453{
 454        jffs2_unregister_compressor(&jffs2_dynrubin_comp);
 455}
 456