18c2ecf20Sopenharmony_ci/* 28c2ecf20Sopenharmony_ci * JFFS2 -- Journalling Flash File System, Version 2. 38c2ecf20Sopenharmony_ci * 48c2ecf20Sopenharmony_ci * Copyright © 2001-2007 Red Hat, Inc. 58c2ecf20Sopenharmony_ci * Copyright © 2004-2010 David Woodhouse <dwmw2@infradead.org> 68c2ecf20Sopenharmony_ci * 78c2ecf20Sopenharmony_ci * Created by Arjan van de Ven <arjanv@redhat.com> 88c2ecf20Sopenharmony_ci * 98c2ecf20Sopenharmony_ci * For licensing information, see the file 'LICENCE' in this directory. 108c2ecf20Sopenharmony_ci * 118c2ecf20Sopenharmony_ci */ 128c2ecf20Sopenharmony_ci 138c2ecf20Sopenharmony_ci#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 148c2ecf20Sopenharmony_ci 158c2ecf20Sopenharmony_ci#include <linux/string.h> 168c2ecf20Sopenharmony_ci#include <linux/types.h> 178c2ecf20Sopenharmony_ci#include <linux/jffs2.h> 188c2ecf20Sopenharmony_ci#include <linux/errno.h> 198c2ecf20Sopenharmony_ci#include "compr.h" 208c2ecf20Sopenharmony_ci 218c2ecf20Sopenharmony_ci 228c2ecf20Sopenharmony_ci#define RUBIN_REG_SIZE 16 238c2ecf20Sopenharmony_ci#define UPPER_BIT_RUBIN (((long) 1)<<(RUBIN_REG_SIZE-1)) 248c2ecf20Sopenharmony_ci#define LOWER_BITS_RUBIN ((((long) 1)<<(RUBIN_REG_SIZE-1))-1) 258c2ecf20Sopenharmony_ci 268c2ecf20Sopenharmony_ci 278c2ecf20Sopenharmony_ci#define BIT_DIVIDER_MIPS 1043 288c2ecf20Sopenharmony_cistatic int bits_mips[8] = { 277, 249, 290, 267, 229, 341, 212, 241}; 298c2ecf20Sopenharmony_ci 308c2ecf20Sopenharmony_cistruct pushpull { 318c2ecf20Sopenharmony_ci unsigned char *buf; 328c2ecf20Sopenharmony_ci unsigned int buflen; 338c2ecf20Sopenharmony_ci unsigned int ofs; 348c2ecf20Sopenharmony_ci unsigned int reserve; 358c2ecf20Sopenharmony_ci}; 368c2ecf20Sopenharmony_ci 378c2ecf20Sopenharmony_cistruct rubin_state { 388c2ecf20Sopenharmony_ci unsigned long p; 398c2ecf20Sopenharmony_ci unsigned long q; 408c2ecf20Sopenharmony_ci unsigned long rec_q; 418c2ecf20Sopenharmony_ci long bit_number; 428c2ecf20Sopenharmony_ci struct pushpull pp; 438c2ecf20Sopenharmony_ci int bit_divider; 448c2ecf20Sopenharmony_ci int bits[8]; 458c2ecf20Sopenharmony_ci}; 468c2ecf20Sopenharmony_ci 478c2ecf20Sopenharmony_cistatic inline void init_pushpull(struct pushpull *pp, char *buf, 488c2ecf20Sopenharmony_ci unsigned buflen, unsigned ofs, 498c2ecf20Sopenharmony_ci unsigned reserve) 508c2ecf20Sopenharmony_ci{ 518c2ecf20Sopenharmony_ci pp->buf = buf; 528c2ecf20Sopenharmony_ci pp->buflen = buflen; 538c2ecf20Sopenharmony_ci pp->ofs = ofs; 548c2ecf20Sopenharmony_ci pp->reserve = reserve; 558c2ecf20Sopenharmony_ci} 568c2ecf20Sopenharmony_ci 578c2ecf20Sopenharmony_cistatic inline int pushbit(struct pushpull *pp, int bit, int use_reserved) 588c2ecf20Sopenharmony_ci{ 598c2ecf20Sopenharmony_ci if (pp->ofs >= pp->buflen - (use_reserved?0:pp->reserve)) 608c2ecf20Sopenharmony_ci return -ENOSPC; 618c2ecf20Sopenharmony_ci 628c2ecf20Sopenharmony_ci if (bit) 638c2ecf20Sopenharmony_ci pp->buf[pp->ofs >> 3] |= (1<<(7-(pp->ofs & 7))); 648c2ecf20Sopenharmony_ci else 658c2ecf20Sopenharmony_ci pp->buf[pp->ofs >> 3] &= ~(1<<(7-(pp->ofs & 7))); 668c2ecf20Sopenharmony_ci 678c2ecf20Sopenharmony_ci pp->ofs++; 688c2ecf20Sopenharmony_ci 698c2ecf20Sopenharmony_ci return 0; 708c2ecf20Sopenharmony_ci} 718c2ecf20Sopenharmony_ci 728c2ecf20Sopenharmony_cistatic inline int pushedbits(struct pushpull *pp) 738c2ecf20Sopenharmony_ci{ 748c2ecf20Sopenharmony_ci return pp->ofs; 758c2ecf20Sopenharmony_ci} 768c2ecf20Sopenharmony_ci 778c2ecf20Sopenharmony_cistatic inline int pullbit(struct pushpull *pp) 788c2ecf20Sopenharmony_ci{ 798c2ecf20Sopenharmony_ci int bit; 808c2ecf20Sopenharmony_ci 818c2ecf20Sopenharmony_ci bit = (pp->buf[pp->ofs >> 3] >> (7-(pp->ofs & 7))) & 1; 828c2ecf20Sopenharmony_ci 838c2ecf20Sopenharmony_ci pp->ofs++; 848c2ecf20Sopenharmony_ci return bit; 858c2ecf20Sopenharmony_ci} 868c2ecf20Sopenharmony_ci 878c2ecf20Sopenharmony_ci 888c2ecf20Sopenharmony_cistatic void init_rubin(struct rubin_state *rs, int div, int *bits) 898c2ecf20Sopenharmony_ci{ 908c2ecf20Sopenharmony_ci int c; 918c2ecf20Sopenharmony_ci 928c2ecf20Sopenharmony_ci rs->q = 0; 938c2ecf20Sopenharmony_ci rs->p = (long) (2 * UPPER_BIT_RUBIN); 948c2ecf20Sopenharmony_ci rs->bit_number = (long) 0; 958c2ecf20Sopenharmony_ci rs->bit_divider = div; 968c2ecf20Sopenharmony_ci 978c2ecf20Sopenharmony_ci for (c=0; c<8; c++) 988c2ecf20Sopenharmony_ci rs->bits[c] = bits[c]; 998c2ecf20Sopenharmony_ci} 1008c2ecf20Sopenharmony_ci 1018c2ecf20Sopenharmony_ci 1028c2ecf20Sopenharmony_cistatic int encode(struct rubin_state *rs, long A, long B, int symbol) 1038c2ecf20Sopenharmony_ci{ 1048c2ecf20Sopenharmony_ci 1058c2ecf20Sopenharmony_ci long i0, i1; 1068c2ecf20Sopenharmony_ci int ret; 1078c2ecf20Sopenharmony_ci 1088c2ecf20Sopenharmony_ci while ((rs->q >= UPPER_BIT_RUBIN) || 1098c2ecf20Sopenharmony_ci ((rs->p + rs->q) <= UPPER_BIT_RUBIN)) { 1108c2ecf20Sopenharmony_ci rs->bit_number++; 1118c2ecf20Sopenharmony_ci 1128c2ecf20Sopenharmony_ci ret = pushbit(&rs->pp, (rs->q & UPPER_BIT_RUBIN) ? 1 : 0, 0); 1138c2ecf20Sopenharmony_ci if (ret) 1148c2ecf20Sopenharmony_ci return ret; 1158c2ecf20Sopenharmony_ci rs->q &= LOWER_BITS_RUBIN; 1168c2ecf20Sopenharmony_ci rs->q <<= 1; 1178c2ecf20Sopenharmony_ci rs->p <<= 1; 1188c2ecf20Sopenharmony_ci } 1198c2ecf20Sopenharmony_ci i0 = A * rs->p / (A + B); 1208c2ecf20Sopenharmony_ci if (i0 <= 0) 1218c2ecf20Sopenharmony_ci i0 = 1; 1228c2ecf20Sopenharmony_ci 1238c2ecf20Sopenharmony_ci if (i0 >= rs->p) 1248c2ecf20Sopenharmony_ci i0 = rs->p - 1; 1258c2ecf20Sopenharmony_ci 1268c2ecf20Sopenharmony_ci i1 = rs->p - i0; 1278c2ecf20Sopenharmony_ci 1288c2ecf20Sopenharmony_ci if (symbol == 0) 1298c2ecf20Sopenharmony_ci rs->p = i0; 1308c2ecf20Sopenharmony_ci else { 1318c2ecf20Sopenharmony_ci rs->p = i1; 1328c2ecf20Sopenharmony_ci rs->q += i0; 1338c2ecf20Sopenharmony_ci } 1348c2ecf20Sopenharmony_ci return 0; 1358c2ecf20Sopenharmony_ci} 1368c2ecf20Sopenharmony_ci 1378c2ecf20Sopenharmony_ci 1388c2ecf20Sopenharmony_cistatic void end_rubin(struct rubin_state *rs) 1398c2ecf20Sopenharmony_ci{ 1408c2ecf20Sopenharmony_ci 1418c2ecf20Sopenharmony_ci int i; 1428c2ecf20Sopenharmony_ci 1438c2ecf20Sopenharmony_ci for (i = 0; i < RUBIN_REG_SIZE; i++) { 1448c2ecf20Sopenharmony_ci pushbit(&rs->pp, (UPPER_BIT_RUBIN & rs->q) ? 1 : 0, 1); 1458c2ecf20Sopenharmony_ci rs->q &= LOWER_BITS_RUBIN; 1468c2ecf20Sopenharmony_ci rs->q <<= 1; 1478c2ecf20Sopenharmony_ci } 1488c2ecf20Sopenharmony_ci} 1498c2ecf20Sopenharmony_ci 1508c2ecf20Sopenharmony_ci 1518c2ecf20Sopenharmony_cistatic void init_decode(struct rubin_state *rs, int div, int *bits) 1528c2ecf20Sopenharmony_ci{ 1538c2ecf20Sopenharmony_ci init_rubin(rs, div, bits); 1548c2ecf20Sopenharmony_ci 1558c2ecf20Sopenharmony_ci /* behalve lower */ 1568c2ecf20Sopenharmony_ci rs->rec_q = 0; 1578c2ecf20Sopenharmony_ci 1588c2ecf20Sopenharmony_ci for (rs->bit_number = 0; rs->bit_number++ < RUBIN_REG_SIZE; 1598c2ecf20Sopenharmony_ci rs->rec_q = rs->rec_q * 2 + (long) (pullbit(&rs->pp))) 1608c2ecf20Sopenharmony_ci ; 1618c2ecf20Sopenharmony_ci} 1628c2ecf20Sopenharmony_ci 1638c2ecf20Sopenharmony_cistatic void __do_decode(struct rubin_state *rs, unsigned long p, 1648c2ecf20Sopenharmony_ci unsigned long q) 1658c2ecf20Sopenharmony_ci{ 1668c2ecf20Sopenharmony_ci register unsigned long lower_bits_rubin = LOWER_BITS_RUBIN; 1678c2ecf20Sopenharmony_ci unsigned long rec_q; 1688c2ecf20Sopenharmony_ci int c, bits = 0; 1698c2ecf20Sopenharmony_ci 1708c2ecf20Sopenharmony_ci /* 1718c2ecf20Sopenharmony_ci * First, work out how many bits we need from the input stream. 1728c2ecf20Sopenharmony_ci * Note that we have already done the initial check on this 1738c2ecf20Sopenharmony_ci * loop prior to calling this function. 1748c2ecf20Sopenharmony_ci */ 1758c2ecf20Sopenharmony_ci do { 1768c2ecf20Sopenharmony_ci bits++; 1778c2ecf20Sopenharmony_ci q &= lower_bits_rubin; 1788c2ecf20Sopenharmony_ci q <<= 1; 1798c2ecf20Sopenharmony_ci p <<= 1; 1808c2ecf20Sopenharmony_ci } while ((q >= UPPER_BIT_RUBIN) || ((p + q) <= UPPER_BIT_RUBIN)); 1818c2ecf20Sopenharmony_ci 1828c2ecf20Sopenharmony_ci rs->p = p; 1838c2ecf20Sopenharmony_ci rs->q = q; 1848c2ecf20Sopenharmony_ci 1858c2ecf20Sopenharmony_ci rs->bit_number += bits; 1868c2ecf20Sopenharmony_ci 1878c2ecf20Sopenharmony_ci /* 1888c2ecf20Sopenharmony_ci * Now get the bits. We really want this to be "get n bits". 1898c2ecf20Sopenharmony_ci */ 1908c2ecf20Sopenharmony_ci rec_q = rs->rec_q; 1918c2ecf20Sopenharmony_ci do { 1928c2ecf20Sopenharmony_ci c = pullbit(&rs->pp); 1938c2ecf20Sopenharmony_ci rec_q &= lower_bits_rubin; 1948c2ecf20Sopenharmony_ci rec_q <<= 1; 1958c2ecf20Sopenharmony_ci rec_q += c; 1968c2ecf20Sopenharmony_ci } while (--bits); 1978c2ecf20Sopenharmony_ci rs->rec_q = rec_q; 1988c2ecf20Sopenharmony_ci} 1998c2ecf20Sopenharmony_ci 2008c2ecf20Sopenharmony_cistatic int decode(struct rubin_state *rs, long A, long B) 2018c2ecf20Sopenharmony_ci{ 2028c2ecf20Sopenharmony_ci unsigned long p = rs->p, q = rs->q; 2038c2ecf20Sopenharmony_ci long i0, threshold; 2048c2ecf20Sopenharmony_ci int symbol; 2058c2ecf20Sopenharmony_ci 2068c2ecf20Sopenharmony_ci if (q >= UPPER_BIT_RUBIN || ((p + q) <= UPPER_BIT_RUBIN)) 2078c2ecf20Sopenharmony_ci __do_decode(rs, p, q); 2088c2ecf20Sopenharmony_ci 2098c2ecf20Sopenharmony_ci i0 = A * rs->p / (A + B); 2108c2ecf20Sopenharmony_ci if (i0 <= 0) 2118c2ecf20Sopenharmony_ci i0 = 1; 2128c2ecf20Sopenharmony_ci 2138c2ecf20Sopenharmony_ci if (i0 >= rs->p) 2148c2ecf20Sopenharmony_ci i0 = rs->p - 1; 2158c2ecf20Sopenharmony_ci 2168c2ecf20Sopenharmony_ci threshold = rs->q + i0; 2178c2ecf20Sopenharmony_ci symbol = rs->rec_q >= threshold; 2188c2ecf20Sopenharmony_ci if (rs->rec_q >= threshold) { 2198c2ecf20Sopenharmony_ci rs->q += i0; 2208c2ecf20Sopenharmony_ci i0 = rs->p - i0; 2218c2ecf20Sopenharmony_ci } 2228c2ecf20Sopenharmony_ci 2238c2ecf20Sopenharmony_ci rs->p = i0; 2248c2ecf20Sopenharmony_ci 2258c2ecf20Sopenharmony_ci return symbol; 2268c2ecf20Sopenharmony_ci} 2278c2ecf20Sopenharmony_ci 2288c2ecf20Sopenharmony_ci 2298c2ecf20Sopenharmony_ci 2308c2ecf20Sopenharmony_cistatic int out_byte(struct rubin_state *rs, unsigned char byte) 2318c2ecf20Sopenharmony_ci{ 2328c2ecf20Sopenharmony_ci int i, ret; 2338c2ecf20Sopenharmony_ci struct rubin_state rs_copy; 2348c2ecf20Sopenharmony_ci rs_copy = *rs; 2358c2ecf20Sopenharmony_ci 2368c2ecf20Sopenharmony_ci for (i=0; i<8; i++) { 2378c2ecf20Sopenharmony_ci ret = encode(rs, rs->bit_divider-rs->bits[i], 2388c2ecf20Sopenharmony_ci rs->bits[i], byte & 1); 2398c2ecf20Sopenharmony_ci if (ret) { 2408c2ecf20Sopenharmony_ci /* Failed. Restore old state */ 2418c2ecf20Sopenharmony_ci *rs = rs_copy; 2428c2ecf20Sopenharmony_ci return ret; 2438c2ecf20Sopenharmony_ci } 2448c2ecf20Sopenharmony_ci byte >>= 1 ; 2458c2ecf20Sopenharmony_ci } 2468c2ecf20Sopenharmony_ci return 0; 2478c2ecf20Sopenharmony_ci} 2488c2ecf20Sopenharmony_ci 2498c2ecf20Sopenharmony_cistatic int in_byte(struct rubin_state *rs) 2508c2ecf20Sopenharmony_ci{ 2518c2ecf20Sopenharmony_ci int i, result = 0, bit_divider = rs->bit_divider; 2528c2ecf20Sopenharmony_ci 2538c2ecf20Sopenharmony_ci for (i = 0; i < 8; i++) 2548c2ecf20Sopenharmony_ci result |= decode(rs, bit_divider - rs->bits[i], 2558c2ecf20Sopenharmony_ci rs->bits[i]) << i; 2568c2ecf20Sopenharmony_ci 2578c2ecf20Sopenharmony_ci return result; 2588c2ecf20Sopenharmony_ci} 2598c2ecf20Sopenharmony_ci 2608c2ecf20Sopenharmony_ci 2618c2ecf20Sopenharmony_ci 2628c2ecf20Sopenharmony_cistatic int rubin_do_compress(int bit_divider, int *bits, unsigned char *data_in, 2638c2ecf20Sopenharmony_ci unsigned char *cpage_out, uint32_t *sourcelen, 2648c2ecf20Sopenharmony_ci uint32_t *dstlen) 2658c2ecf20Sopenharmony_ci { 2668c2ecf20Sopenharmony_ci int outpos = 0; 2678c2ecf20Sopenharmony_ci int pos=0; 2688c2ecf20Sopenharmony_ci struct rubin_state rs; 2698c2ecf20Sopenharmony_ci 2708c2ecf20Sopenharmony_ci init_pushpull(&rs.pp, cpage_out, *dstlen * 8, 0, 32); 2718c2ecf20Sopenharmony_ci 2728c2ecf20Sopenharmony_ci init_rubin(&rs, bit_divider, bits); 2738c2ecf20Sopenharmony_ci 2748c2ecf20Sopenharmony_ci while (pos < (*sourcelen) && !out_byte(&rs, data_in[pos])) 2758c2ecf20Sopenharmony_ci pos++; 2768c2ecf20Sopenharmony_ci 2778c2ecf20Sopenharmony_ci end_rubin(&rs); 2788c2ecf20Sopenharmony_ci 2798c2ecf20Sopenharmony_ci if (outpos > pos) { 2808c2ecf20Sopenharmony_ci /* We failed */ 2818c2ecf20Sopenharmony_ci return -1; 2828c2ecf20Sopenharmony_ci } 2838c2ecf20Sopenharmony_ci 2848c2ecf20Sopenharmony_ci /* Tell the caller how much we managed to compress, 2858c2ecf20Sopenharmony_ci * and how much space it took */ 2868c2ecf20Sopenharmony_ci 2878c2ecf20Sopenharmony_ci outpos = (pushedbits(&rs.pp)+7)/8; 2888c2ecf20Sopenharmony_ci 2898c2ecf20Sopenharmony_ci if (outpos >= pos) 2908c2ecf20Sopenharmony_ci return -1; /* We didn't actually compress */ 2918c2ecf20Sopenharmony_ci *sourcelen = pos; 2928c2ecf20Sopenharmony_ci *dstlen = outpos; 2938c2ecf20Sopenharmony_ci return 0; 2948c2ecf20Sopenharmony_ci} 2958c2ecf20Sopenharmony_ci#if 0 2968c2ecf20Sopenharmony_ci/* _compress returns the compressed size, -1 if bigger */ 2978c2ecf20Sopenharmony_ciint jffs2_rubinmips_compress(unsigned char *data_in, unsigned char *cpage_out, 2988c2ecf20Sopenharmony_ci uint32_t *sourcelen, uint32_t *dstlen) 2998c2ecf20Sopenharmony_ci{ 3008c2ecf20Sopenharmony_ci return rubin_do_compress(BIT_DIVIDER_MIPS, bits_mips, data_in, 3018c2ecf20Sopenharmony_ci cpage_out, sourcelen, dstlen); 3028c2ecf20Sopenharmony_ci} 3038c2ecf20Sopenharmony_ci#endif 3048c2ecf20Sopenharmony_cistatic int jffs2_dynrubin_compress(unsigned char *data_in, 3058c2ecf20Sopenharmony_ci unsigned char *cpage_out, 3068c2ecf20Sopenharmony_ci uint32_t *sourcelen, uint32_t *dstlen) 3078c2ecf20Sopenharmony_ci{ 3088c2ecf20Sopenharmony_ci int bits[8]; 3098c2ecf20Sopenharmony_ci unsigned char histo[256]; 3108c2ecf20Sopenharmony_ci int i; 3118c2ecf20Sopenharmony_ci int ret; 3128c2ecf20Sopenharmony_ci uint32_t mysrclen, mydstlen; 3138c2ecf20Sopenharmony_ci 3148c2ecf20Sopenharmony_ci mysrclen = *sourcelen; 3158c2ecf20Sopenharmony_ci mydstlen = *dstlen - 8; 3168c2ecf20Sopenharmony_ci 3178c2ecf20Sopenharmony_ci if (*dstlen <= 12) 3188c2ecf20Sopenharmony_ci return -1; 3198c2ecf20Sopenharmony_ci 3208c2ecf20Sopenharmony_ci memset(histo, 0, 256); 3218c2ecf20Sopenharmony_ci for (i=0; i<mysrclen; i++) 3228c2ecf20Sopenharmony_ci histo[data_in[i]]++; 3238c2ecf20Sopenharmony_ci memset(bits, 0, sizeof(int)*8); 3248c2ecf20Sopenharmony_ci for (i=0; i<256; i++) { 3258c2ecf20Sopenharmony_ci if (i&128) 3268c2ecf20Sopenharmony_ci bits[7] += histo[i]; 3278c2ecf20Sopenharmony_ci if (i&64) 3288c2ecf20Sopenharmony_ci bits[6] += histo[i]; 3298c2ecf20Sopenharmony_ci if (i&32) 3308c2ecf20Sopenharmony_ci bits[5] += histo[i]; 3318c2ecf20Sopenharmony_ci if (i&16) 3328c2ecf20Sopenharmony_ci bits[4] += histo[i]; 3338c2ecf20Sopenharmony_ci if (i&8) 3348c2ecf20Sopenharmony_ci bits[3] += histo[i]; 3358c2ecf20Sopenharmony_ci if (i&4) 3368c2ecf20Sopenharmony_ci bits[2] += histo[i]; 3378c2ecf20Sopenharmony_ci if (i&2) 3388c2ecf20Sopenharmony_ci bits[1] += histo[i]; 3398c2ecf20Sopenharmony_ci if (i&1) 3408c2ecf20Sopenharmony_ci bits[0] += histo[i]; 3418c2ecf20Sopenharmony_ci } 3428c2ecf20Sopenharmony_ci 3438c2ecf20Sopenharmony_ci for (i=0; i<8; i++) { 3448c2ecf20Sopenharmony_ci bits[i] = (bits[i] * 256) / mysrclen; 3458c2ecf20Sopenharmony_ci if (!bits[i]) bits[i] = 1; 3468c2ecf20Sopenharmony_ci if (bits[i] > 255) bits[i] = 255; 3478c2ecf20Sopenharmony_ci cpage_out[i] = bits[i]; 3488c2ecf20Sopenharmony_ci } 3498c2ecf20Sopenharmony_ci 3508c2ecf20Sopenharmony_ci ret = rubin_do_compress(256, bits, data_in, cpage_out+8, &mysrclen, 3518c2ecf20Sopenharmony_ci &mydstlen); 3528c2ecf20Sopenharmony_ci if (ret) 3538c2ecf20Sopenharmony_ci return ret; 3548c2ecf20Sopenharmony_ci 3558c2ecf20Sopenharmony_ci /* Add back the 8 bytes we took for the probabilities */ 3568c2ecf20Sopenharmony_ci mydstlen += 8; 3578c2ecf20Sopenharmony_ci 3588c2ecf20Sopenharmony_ci if (mysrclen <= mydstlen) { 3598c2ecf20Sopenharmony_ci /* We compressed */ 3608c2ecf20Sopenharmony_ci return -1; 3618c2ecf20Sopenharmony_ci } 3628c2ecf20Sopenharmony_ci 3638c2ecf20Sopenharmony_ci *sourcelen = mysrclen; 3648c2ecf20Sopenharmony_ci *dstlen = mydstlen; 3658c2ecf20Sopenharmony_ci return 0; 3668c2ecf20Sopenharmony_ci} 3678c2ecf20Sopenharmony_ci 3688c2ecf20Sopenharmony_cistatic void rubin_do_decompress(int bit_divider, int *bits, 3698c2ecf20Sopenharmony_ci unsigned char *cdata_in, 3708c2ecf20Sopenharmony_ci unsigned char *page_out, uint32_t srclen, 3718c2ecf20Sopenharmony_ci uint32_t destlen) 3728c2ecf20Sopenharmony_ci{ 3738c2ecf20Sopenharmony_ci int outpos = 0; 3748c2ecf20Sopenharmony_ci struct rubin_state rs; 3758c2ecf20Sopenharmony_ci 3768c2ecf20Sopenharmony_ci init_pushpull(&rs.pp, cdata_in, srclen, 0, 0); 3778c2ecf20Sopenharmony_ci init_decode(&rs, bit_divider, bits); 3788c2ecf20Sopenharmony_ci 3798c2ecf20Sopenharmony_ci while (outpos < destlen) 3808c2ecf20Sopenharmony_ci page_out[outpos++] = in_byte(&rs); 3818c2ecf20Sopenharmony_ci} 3828c2ecf20Sopenharmony_ci 3838c2ecf20Sopenharmony_ci 3848c2ecf20Sopenharmony_cistatic int jffs2_rubinmips_decompress(unsigned char *data_in, 3858c2ecf20Sopenharmony_ci unsigned char *cpage_out, 3868c2ecf20Sopenharmony_ci uint32_t sourcelen, uint32_t dstlen) 3878c2ecf20Sopenharmony_ci{ 3888c2ecf20Sopenharmony_ci rubin_do_decompress(BIT_DIVIDER_MIPS, bits_mips, data_in, 3898c2ecf20Sopenharmony_ci cpage_out, sourcelen, dstlen); 3908c2ecf20Sopenharmony_ci return 0; 3918c2ecf20Sopenharmony_ci} 3928c2ecf20Sopenharmony_ci 3938c2ecf20Sopenharmony_cistatic int jffs2_dynrubin_decompress(unsigned char *data_in, 3948c2ecf20Sopenharmony_ci unsigned char *cpage_out, 3958c2ecf20Sopenharmony_ci uint32_t sourcelen, uint32_t dstlen) 3968c2ecf20Sopenharmony_ci{ 3978c2ecf20Sopenharmony_ci int bits[8]; 3988c2ecf20Sopenharmony_ci int c; 3998c2ecf20Sopenharmony_ci 4008c2ecf20Sopenharmony_ci for (c=0; c<8; c++) 4018c2ecf20Sopenharmony_ci bits[c] = data_in[c]; 4028c2ecf20Sopenharmony_ci 4038c2ecf20Sopenharmony_ci rubin_do_decompress(256, bits, data_in+8, cpage_out, sourcelen-8, 4048c2ecf20Sopenharmony_ci dstlen); 4058c2ecf20Sopenharmony_ci return 0; 4068c2ecf20Sopenharmony_ci} 4078c2ecf20Sopenharmony_ci 4088c2ecf20Sopenharmony_cistatic struct jffs2_compressor jffs2_rubinmips_comp = { 4098c2ecf20Sopenharmony_ci .priority = JFFS2_RUBINMIPS_PRIORITY, 4108c2ecf20Sopenharmony_ci .name = "rubinmips", 4118c2ecf20Sopenharmony_ci .compr = JFFS2_COMPR_DYNRUBIN, 4128c2ecf20Sopenharmony_ci .compress = NULL, /*&jffs2_rubinmips_compress,*/ 4138c2ecf20Sopenharmony_ci .decompress = &jffs2_rubinmips_decompress, 4148c2ecf20Sopenharmony_ci#ifdef JFFS2_RUBINMIPS_DISABLED 4158c2ecf20Sopenharmony_ci .disabled = 1, 4168c2ecf20Sopenharmony_ci#else 4178c2ecf20Sopenharmony_ci .disabled = 0, 4188c2ecf20Sopenharmony_ci#endif 4198c2ecf20Sopenharmony_ci}; 4208c2ecf20Sopenharmony_ci 4218c2ecf20Sopenharmony_ciint jffs2_rubinmips_init(void) 4228c2ecf20Sopenharmony_ci{ 4238c2ecf20Sopenharmony_ci return jffs2_register_compressor(&jffs2_rubinmips_comp); 4248c2ecf20Sopenharmony_ci} 4258c2ecf20Sopenharmony_ci 4268c2ecf20Sopenharmony_civoid jffs2_rubinmips_exit(void) 4278c2ecf20Sopenharmony_ci{ 4288c2ecf20Sopenharmony_ci jffs2_unregister_compressor(&jffs2_rubinmips_comp); 4298c2ecf20Sopenharmony_ci} 4308c2ecf20Sopenharmony_ci 4318c2ecf20Sopenharmony_cistatic struct jffs2_compressor jffs2_dynrubin_comp = { 4328c2ecf20Sopenharmony_ci .priority = JFFS2_DYNRUBIN_PRIORITY, 4338c2ecf20Sopenharmony_ci .name = "dynrubin", 4348c2ecf20Sopenharmony_ci .compr = JFFS2_COMPR_RUBINMIPS, 4358c2ecf20Sopenharmony_ci .compress = jffs2_dynrubin_compress, 4368c2ecf20Sopenharmony_ci .decompress = &jffs2_dynrubin_decompress, 4378c2ecf20Sopenharmony_ci#ifdef JFFS2_DYNRUBIN_DISABLED 4388c2ecf20Sopenharmony_ci .disabled = 1, 4398c2ecf20Sopenharmony_ci#else 4408c2ecf20Sopenharmony_ci .disabled = 0, 4418c2ecf20Sopenharmony_ci#endif 4428c2ecf20Sopenharmony_ci}; 4438c2ecf20Sopenharmony_ci 4448c2ecf20Sopenharmony_ciint jffs2_dynrubin_init(void) 4458c2ecf20Sopenharmony_ci{ 4468c2ecf20Sopenharmony_ci return jffs2_register_compressor(&jffs2_dynrubin_comp); 4478c2ecf20Sopenharmony_ci} 4488c2ecf20Sopenharmony_ci 4498c2ecf20Sopenharmony_civoid jffs2_dynrubin_exit(void) 4508c2ecf20Sopenharmony_ci{ 4518c2ecf20Sopenharmony_ci jffs2_unregister_compressor(&jffs2_dynrubin_comp); 4528c2ecf20Sopenharmony_ci} 453