diff options
Diffstat (limited to 'openwrt/target/linux/generic-2.4/patches/003-jffs2_compression.patch')
-rw-r--r-- | openwrt/target/linux/generic-2.4/patches/003-jffs2_compression.patch | 9119 |
1 files changed, 0 insertions, 9119 deletions
diff --git a/openwrt/target/linux/generic-2.4/patches/003-jffs2_compression.patch b/openwrt/target/linux/generic-2.4/patches/003-jffs2_compression.patch deleted file mode 100644 index 56c5b3c..0000000 --- a/openwrt/target/linux/generic-2.4/patches/003-jffs2_compression.patch +++ /dev/null @@ -1,9119 +0,0 @@ -diff -Nur linux-mips-cvs/Documentation/Configure.help linux-mips/Documentation/Configure.help ---- linux-mips-cvs/Documentation/Configure.help 2005-01-20 03:19:21.000000000 +0100 -+++ linux-mips/Documentation/Configure.help 2005-02-07 05:08:35.000000000 +0100 -@@ -17528,6 +17528,32 @@ - If reporting bugs, please try to have available a full dump of the - messages at debug level 1 while the misbehaviour was occurring. - -+ARMLIB compression support for BBC (EXPERIMENTAL) -+CONFIG_JFFS2_BBC_ARMLIB -+ This enables ARMLIB support for BBC. -+ -+LZO1X-* compression support for BBC (EXPERIMENTAL) -+CONFIG_JFFS2_BBC_LZO -+ This enables LZO1X-1 and LZO1X-999 support for BBC. (fast & good -+ compressor, beats ZLIB in everything) -+ -+LZARI compression support for BBC (EXPERIMENTAL) -+CONFIG_JFFS2_BBC_LZARI -+ This enables LempelZiv-Storer-Szymanski compression for BBC with -+ additional arithmetic coding (damn slow, but best compresor). -+ -+LZHD compression support for BBC (EXPERIMENTAL) -+CONFIG_JFFS2_BBC_LZHD -+ This enables LempelZiv-Storer-Szymanski compression for BBC with -+ additional dynamic Huffman coding (a little faster than LZARI, and -+ it's compression ratio is a little worse than LZARI's) -+ -+LZSS compression support for BBC (EXPERIMENTAL) -+CONFIG_JFFS2_BBC_LZSS -+ This enables simple LempelZiv-Storer-Szymanski compression for BBC -+ (faster than LZHD, and, and has a not-so-good compression ratio, -+ was included just for testing) -+ - JFFS stats available in /proc filesystem - CONFIG_JFFS_PROC_FS - Enabling this option will cause statistics from mounted JFFS file systems -diff -Nur linux-mips-cvs/fs/Config.in linux-mips/fs/Config.in ---- linux-mips-cvs/fs/Config.in 2004-11-19 01:28:47.000000000 +0100 -+++ linux-mips/fs/Config.in 2005-02-07 05:08:34.000000000 +0100 -@@ -50,6 +50,12 @@ - if [ "$CONFIG_JFFS2_FS" = "y" -o "$CONFIG_JFFS2_FS" = "m" ] ; then - int 'JFFS2 debugging verbosity (0 = quiet, 2 = noisy)' CONFIG_JFFS2_FS_DEBUG 0 - fi -+dep_mbool ' ARMLIB compression support for BBC (EXPERIMENTAL)' CONFIG_JFFS2_BBC_ARMLIB $CONFIG_JFFS2_FS -+dep_mbool ' LZO1X-* compression support for BBC (EXPERIMENTAL)' CONFIG_JFFS2_BBC_LZO $CONFIG_JFFS2_FS -+dep_mbool ' LZARI compression support for BBC (EXPERIMENTAL)' CONFIG_JFFS2_BBC_LZARI $CONFIG_JFFS2_FS -+dep_mbool ' LZHD compression support for BBC (EXPERIMENTAL)' CONFIG_JFFS2_BBC_LZHD $CONFIG_JFFS2_FS -+dep_mbool ' LZSS compression support for BBC (EXPERIMENTAL)' CONFIG_JFFS2_BBC_LZSS $CONFIG_JFFS2_FS -+ - tristate 'Compressed ROM file system support' CONFIG_CRAMFS - bool 'Virtual memory file system support (former shm fs)' CONFIG_TMPFS - define_bool CONFIG_RAMFS y -diff -Nur linux-mips-cvs/fs/jffs2/Config.in.bbc.inc linux-mips/fs/jffs2/Config.in.bbc.inc ---- linux-mips-cvs/fs/jffs2/Config.in.bbc.inc 1970-01-01 01:00:00.000000000 +0100 -+++ linux-mips/fs/jffs2/Config.in.bbc.inc 2005-02-07 05:08:34.000000000 +0100 -@@ -0,0 +1,5 @@ -+dep_mbool ' ARMLIB compression support for BBC (EXPERIMENTAL)' CONFIG_JFFS2_BBC_ARMLIB $CONFIG_JFFS2_FS -+dep_mbool ' LZO1X-* compression support for BBC (EXPERIMENTAL)' CONFIG_JFFS2_BBC_LZO $CONFIG_JFFS2_FS -+dep_mbool ' LZARI compression support for BBC (EXPERIMENTAL)' CONFIG_JFFS2_BBC_LZARI $CONFIG_JFFS2_FS -+dep_mbool ' LZHD compression support for BBC (EXPERIMENTAL)' CONFIG_JFFS2_BBC_LZHD $CONFIG_JFFS2_FS -+dep_mbool ' LZSS compression support for BBC (EXPERIMENTAL)' CONFIG_JFFS2_BBC_LZSS $CONFIG_JFFS2_FS -diff -Nur linux-mips-cvs/fs/jffs2/Configure.help.bbc.inc linux-mips/fs/jffs2/Configure.help.bbc.inc ---- linux-mips-cvs/fs/jffs2/Configure.help.bbc.inc 1970-01-01 01:00:00.000000000 +0100 -+++ linux-mips/fs/jffs2/Configure.help.bbc.inc 2005-02-07 05:08:34.000000000 +0100 -@@ -0,0 +1,25 @@ -+ARMLIB compression support for BBC (EXPERIMENTAL) -+CONFIG_JFFS2_BBC_ARMLIB -+ This enables ARMLIB support for BBC. -+ -+LZO1X-* compression support for BBC (EXPERIMENTAL) -+CONFIG_JFFS2_BBC_LZO -+ This enables LZO1X-1 and LZO1X-999 support for BBC. (fast & good -+ compressor, beats ZLIB in everything) -+ -+LZARI compression support for BBC (EXPERIMENTAL) -+CONFIG_JFFS2_BBC_LZARI -+ This enables LempelZiv-Storer-Szymanski compression for BBC with -+ additional arithmetic coding (damn slow, but best compresor). -+ -+LZHD compression support for BBC (EXPERIMENTAL) -+CONFIG_JFFS2_BBC_LZHD -+ This enables LempelZiv-Storer-Szymanski compression for BBC with -+ additional dynamic Huffman coding (a little faster than LZARI, and -+ it's compression ratio is a little worse than LZARI's) -+ -+LZSS compression support for BBC (EXPERIMENTAL) -+CONFIG_JFFS2_BBC_LZSS -+ This enables simple LempelZiv-Storer-Szymanski compression for BBC -+ (faster than LZHD, and, and has a not-so-good compression ratio, -+ was included just for testing) -diff -Nur linux-mips-cvs/fs/jffs2/Kconfig.bbc.inc linux-mips/fs/jffs2/Kconfig.bbc.inc ---- linux-mips-cvs/fs/jffs2/Kconfig.bbc.inc 1970-01-01 01:00:00.000000000 +0100 -+++ linux-mips/fs/jffs2/Kconfig.bbc.inc 2005-02-07 05:08:34.000000000 +0100 -@@ -0,0 +1,40 @@ -+config JFFS2_BBC_ARMLIB -+ bool "ARMLIB compression support for BBC (EXPERIMENTAL)" -+ depends on JFFS2_FS && EXPERIMENTAL -+ default y -+ help -+ This enables ARMLIB support for BBC. -+ -+config JFFS2_BBC_LZO -+ bool "LZO1X-* compression support for BBC (EXPERIMENTAL)" -+ depends on JFFS2_FS && EXPERIMENTAL -+ default y -+ help -+ This enables LZO1X-1 and LZO1X-999 support for BBC. (fast & good -+ compressor) -+ -+config JFFS2_BBC_LZARI -+ bool "LZARI compression support for BBC (EXPERIMENTAL)" -+ depends on JFFS2_FS && EXPERIMENTAL -+ default y -+ help -+ This enables LempelZiv-Storer-Szymanski compression for BBC with -+ additional arithmetic coding (damn slow, but best compresor). -+ -+config JFFS2_BBC_LZHD -+ bool "LZHD compression support for BBC (EXPERIMENTAL)" -+ depends on JFFS2_FS && EXPERIMENTAL -+ default y -+ help -+ This enables LempelZiv-Storer-Szymanski compression for BBC with -+ additional dynamic Huffman coding (a little faster than LZARI, and -+ it's compression ratio is a little worse than LZARI's) -+ -+config JFFS2_BBC_LZSS -+ bool "LZSS compression support for BBC (EXPERIMENTAL)" -+ depends on JFFS2_FS && EXPERIMENTAL -+ default y -+ help -+ This enables simple LempelZiv-Storer-Szymanski compression for BBC -+ (faster than LZHD, and, and has a not-so-good compression ratio, -+ was included just for testing) -diff -Nur linux-mips-cvs/fs/jffs2/Makefile linux-mips/fs/jffs2/Makefile ---- linux-mips-cvs/fs/jffs2/Makefile 2003-08-13 19:19:25.000000000 +0200 -+++ linux-mips/fs/jffs2/Makefile 2005-02-07 05:08:34.000000000 +0100 -@@ -10,9 +10,23 @@ - # Note 2! The CFLAGS definitions are now in the main makefile... - - -+JFFS2_BBC_KERNEL_OBJS-y = jffs2_bbc_framework.o jffs2_bbc_fs.o -+ -+JFFS2_BBC_KERNEL_OBJS-$(CONFIG_JFFS2_BBC_ARMLIB) += jffs2_bbc_armlib_comp.o -+JFFS2_BBC_KERNEL_OBJS-$(CONFIG_JFFS2_BBC_LZO) += jffs2_bbc_lzo_comp.o -+JFFS2_BBC_KERNEL_OBJS-$(CONFIG_JFFS2_BBC_LZSS) += jffs2_bbc_lzss_comp.o -+JFFS2_BBC_KERNEL_OBJS-$(CONFIG_JFFS2_BBC_LZARI) += jffs2_bbc_lzari_comp.o -+JFFS2_BBC_KERNEL_OBJS-$(CONFIG_JFFS2_BBC_LZHD) += jffs2_bbc_lzhd_comp.o -+ -+JFFS2_BBC_KERNEL_OBJS := $(JFFS2_BBC_KERNEL_OBJS-y) -+ -+JFFS2_BBC_MKFS_OBJS = jffs2_bbc_mkfs.o jffs2_bbc_framework.o jffs2_bbc_armlib_comp.o jffs2_bbc_lzo_comp.o\ -+ jffs2_bbc_lzss_comp.o jffs2_bbc_lzari_comp.o jffs2_bbc_lzhd_comp.o -+ - COMPR_OBJS := compr.o compr_rubin.o compr_rtime.o pushpull.o \ - compr_zlib.o - JFFS2_OBJS := dir.o file.o ioctl.o nodelist.o malloc.o \ -+ $(JFFS2_BBC_KERNEL_OBJS) \ - read.o nodemgmt.o readinode.o super.o write.o scan.o gc.o \ - symlink.o build.o erase.o background.o - -diff -Nur linux-mips-cvs/fs/jffs2/Makefile.bbc.inc linux-mips/fs/jffs2/Makefile.bbc.inc ---- linux-mips-cvs/fs/jffs2/Makefile.bbc.inc 1970-01-01 01:00:00.000000000 +0100 -+++ linux-mips/fs/jffs2/Makefile.bbc.inc 2005-02-07 05:08:34.000000000 +0100 -@@ -0,0 +1,12 @@ -+JFFS2_BBC_KERNEL_OBJS-y = jffs2_bbc_framework.o jffs2_bbc_fs.o -+ -+JFFS2_BBC_KERNEL_OBJS-$(CONFIG_JFFS2_BBC_ARMLIB) += jffs2_bbc_armlib_comp.o -+JFFS2_BBC_KERNEL_OBJS-$(CONFIG_JFFS2_BBC_LZO) += jffs2_bbc_lzo_comp.o -+JFFS2_BBC_KERNEL_OBJS-$(CONFIG_JFFS2_BBC_LZSS) += jffs2_bbc_lzss_comp.o -+JFFS2_BBC_KERNEL_OBJS-$(CONFIG_JFFS2_BBC_LZARI) += jffs2_bbc_lzari_comp.o -+JFFS2_BBC_KERNEL_OBJS-$(CONFIG_JFFS2_BBC_LZHD) += jffs2_bbc_lzhd_comp.o -+ -+JFFS2_BBC_KERNEL_OBJS := $(JFFS2_BBC_KERNEL_OBJS-y) -+ -+JFFS2_BBC_MKFS_OBJS = jffs2_bbc_mkfs.o jffs2_bbc_framework.o jffs2_bbc_armlib_comp.o jffs2_bbc_lzo_comp.o\ -+ jffs2_bbc_lzss_comp.o jffs2_bbc_lzari_comp.o jffs2_bbc_lzhd_comp.o -diff -Nur linux-mips-cvs/fs/jffs2/compr_zlib.c linux-mips/fs/jffs2/compr_zlib.c ---- linux-mips-cvs/fs/jffs2/compr_zlib.c 2003-01-11 18:53:17.000000000 +0100 -+++ linux-mips/fs/jffs2/compr_zlib.c 2005-02-07 05:08:35.000000000 +0100 -@@ -85,7 +85,7 @@ - vfree(inflate_workspace); - } - --int zlib_compress(unsigned char *data_in, unsigned char *cpage_out, -+int jffs2_zlib_compress2(unsigned char *data_in, unsigned char *cpage_out, - __u32 *sourcelen, __u32 *dstlen) - { - z_stream strm; -@@ -145,7 +145,7 @@ - return 0; - } - --void zlib_decompress(unsigned char *data_in, unsigned char *cpage_out, -+void jffs2_zlib_decompress2(unsigned char *data_in, unsigned char *cpage_out, - __u32 srclen, __u32 destlen) - { - z_stream strm; -@@ -175,3 +175,19 @@ - zlib_inflateEnd(&strm); - up(&inflate_sem); - } -+ -+extern int jffs2_zlib_compress(unsigned char *data_in, unsigned char *cpage_out, __u32 * sourcelen, __u32 * dstlen); -+extern void jffs2_zlib_decompress(unsigned char *data_in, unsigned char *cpage_out, __u32 srclen, __u32 destlen); -+ -+int zlib_compress(unsigned char *data_in, unsigned char *cpage_out, -+ __u32 *sourcelen, __u32 *dstlen) -+{ -+ return jffs2_zlib_compress(data_in,cpage_out,sourcelen,dstlen); -+} -+ -+void zlib_decompress(unsigned char *data_in, unsigned char *cpage_out, -+ __u32 srclen, __u32 destlen) -+{ -+ jffs2_zlib_decompress(data_in,cpage_out,srclen,destlen); -+} -+ -diff -Nur linux-mips-cvs/fs/jffs2/file.c linux-mips/fs/jffs2/file.c ---- linux-mips-cvs/fs/jffs2/file.c 2003-11-17 02:07:44.000000000 +0100 -+++ linux-mips/fs/jffs2/file.c 2005-02-07 05:08:35.000000000 +0100 -@@ -35,6 +35,7 @@ - * - */ - -+#include "jffs2_bbc_framework.h" /**BBC**/ - #include <linux/kernel.h> - #include <linux/mtd/compatmac.h> /* for min() */ - #include <linux/slab.h> -@@ -459,6 +460,7 @@ - - comprbuf = kmalloc(cdatalen, GFP_KERNEL); - if (comprbuf) { -+ jffs2_bbc_model_set_act_sb(c); /**BBC**/ - comprtype = jffs2_compress(page_address(pg)+ (file_ofs & (PAGE_CACHE_SIZE-1)), comprbuf, &datalen, &cdatalen); - } - if (comprtype == JFFS2_COMPR_NONE) { -diff -Nur linux-mips-cvs/fs/jffs2/gc.c linux-mips/fs/jffs2/gc.c ---- linux-mips-cvs/fs/jffs2/gc.c 2003-11-17 02:07:44.000000000 +0100 -+++ linux-mips/fs/jffs2/gc.c 2005-02-07 05:08:35.000000000 +0100 -@@ -35,6 +35,7 @@ - * - */ - -+#include "jffs2_bbc_framework.h" /**BBC**/ - #include <linux/kernel.h> - #include <linux/mtd/mtd.h> - #include <linux/slab.h> -@@ -651,6 +652,7 @@ - writebuf = pg_ptr + (offset & (PAGE_CACHE_SIZE -1)); - - if (comprbuf) { -+ jffs2_bbc_model_set_act_sb(c); /**BBC**/ - comprtype = jffs2_compress(writebuf, comprbuf, &datalen, &cdatalen); - } - if (comprtype) { -diff -Nur linux-mips-cvs/fs/jffs2/hpatch linux-mips/fs/jffs2/hpatch ---- linux-mips-cvs/fs/jffs2/hpatch 1970-01-01 01:00:00.000000000 +0100 -+++ linux-mips/fs/jffs2/hpatch 2005-02-07 05:08:34.000000000 +0100 -@@ -0,0 +1,191 @@ -+#!/usr/bin/perl -+# A patch-like utility -+# Designed for patching different version of jffs2 with the same hpatch file -+# -+# Copyright (C) 2004, Ferenc Havasi -+# -+# This program is free software; you can redistribute it and/or -+# modify it under the terms of the GNU General Public License -+# as published by the Free Software Foundation; either version 2 -+# of the License, or (at your option) any later version. -+# -+# This program is distributed in the hope that it will be useful, -+# but WITHOUT ANY WARRANTY; without even the implied warranty of -+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+# GNU General Public License for more details. -+# -+# You should have received a copy of the GNU General Public License -+# along with this program; if not, write to the Free Software -+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -+ -+$filename_tmp1="file1.tmp"; -+$filename_tmp2="file2.tmp"; -+ -+$filename_in=""; -+$filename_out=$filename_tmp1; -+$filename_cnt=0; -+ -+# Modes: -+# 0: expecting = -+# 1: normal_cmd -+# 2: skip until = -+# 3: expecting F (first state) -+$mode=3; -+ -+%rules = (); -+ -+sub file_end { -+ if (($mode!=2)&&($modified==1)) { -+ while (<SRC>) { -+ print DST $_; -+ } -+ close(SRC); -+ close(DST); -+ if ($cmd_name ne "") { $rules{"$cmd_name"}=1; } -+ $filename_result=$filename_out; -+ if ($filename_result ne $filename_in_save) { -+ open(RES,"<$filename_result") or die "Cannot open $filename_result.\n"; -+ open(DST,">$filename_in_save") or die "Cannot open $filename_in_save.\n"; -+ while (<RES>) { -+ print DST $_; -+ } -+ close(DST); -+ close(RES); -+ } -+ unlink($filename_tmp1) && unlink($filename_tmp2); -+ } -+ else { -+ close(SRC); -+ close(DST); -+ $filename_result=$filename_in; -+ if ($filename_result ne $filename_in_save) { -+ open(RES,"<$filename_result") or die "Cannot open $filename_result.\n"; -+ open(DST,">$filename_in_save") or die "Cannot open $filename_in_save.\n"; -+ while (<RES>) { -+ print DST $_; -+ } -+ close(DST); -+ close(RES); -+ } -+ unlink($filename_tmp1); -+ } -+ $modified=0; -+ foreach $rulename (keys %rules) { -+ if ($rules{"$rulename"}==0) { print(STDERR "On $filename_in_save error applying rule $rulename.\n"); } -+ } -+ %rules = (); -+} -+ -+if ($#ARGV<0) { -+ print ("usage: hpatch hpatch_file\n"); -+ exit; -+} -+ -+open(CMD,"<$ARGV[0]") or die "Cannot open $ARGV[0].\n"; -+$cmd_linenum=0; -+ -+while (chomp($cmd_line=<CMD>)) { -+ $cmd_linenum++; -+ if ($cmd_line eq "") {next;} -+ #$cmd_line =~ s/\#.*//; -+ $cmd_line =~ s/\ *$//; -+ if ($cmd_line eq "") {next;} -+ if ($cmd_line =~ /^F(.*)/) { -+ $tmp_filename_in=$1; -+ if ($mode!=3) { -+ file_end(); -+ } -+ $filename_in=$tmp_filename_in; -+ $filename_in_save=$filename_in; -+ open(SRC,"<$filename_in") or die "Cannot open $filename_in.\n"; -+ open(DST,">$filename_out") or die "Cannot open $filename_out.\n";; -+ $modified=0; -+ $mode=0; -+ next; -+ } -+ if ($mode==3) {die "error: F expression expected in line $cmd_linenum\n";} -+ if ($cmd_line =~ /^=(.*)/) { -+ $tmp_cmd_name=$1; -+ if (($mode!=2)&&($modified==1)) { -+ while (<SRC>) { -+ print DST $_; -+ } -+ close(SRC); -+ close(DST); -+ if (($cmd_name ne "")) {$rules{"$cmd_name"}=1;}; -+ $filename_cnt++; -+ if ($filename_cnt%2==1) { -+ $filename_in=$filename_tmp1; -+ $filename_out=$filename_tmp2; -+ } -+ else { -+ $filename_in=$filename_tmp2; -+ $filename_out=$filename_tmp1; -+ } -+ } -+ else { -+ close(SRC); -+ close(DST); -+ } -+ $mode=1; -+ $cmd_name=$tmp_cmd_name; -+ if (($cmd_name ne "")) { -+ if ($rules{"$cmd_name"}==1) { -+ $mode=2; -+ } -+ else { -+ $rules{"$cmd_name"}=0; -+ } -+ } -+ open(SRC,"<$filename_in") or die "Cannot open $filename_in.\n"; -+ open(DST,">$filename_out") or die "Cannot open $filename_out.\n"; -+ $modified=0; -+ next; -+ } -+ if ($mode == 0) {die "error: = expression expected in line $cmd_linenum\n";} -+ if ($mode == 2) {next;} -+ if ($cmd_line =~ /^!(.*)/) { -+ print "$1\n"; -+ $modified=1; -+ next; -+ } -+ if ($cmd_line =~ /^\?(.*)/) { -+ $search_str=$1; -+ $found=0; -+ while (<SRC>) { -+ print DST $_; -+ if (index($_,$search_str)>=0) {$found=1; last;} -+ } -+ if ($found==0) { $mode=2; } -+ next; -+ } -+ if ($cmd_line =~ /^\+(.*)/) { -+ print DST "$1\n"; -+ $modified=1; -+ next; -+ } -+ if ($cmd_line =~ /^\-(.*)/) { -+ $search_str=$1; -+ $found=0; -+ while (<SRC>) { -+ if (index($_,$search_str)>=0) {$saved_line=$_; $found=1; $modified=1; last;} -+ print DST $_; -+ } -+ if ($found==0) { $mode=2; } -+ next; -+ } -+ if ($cmd_line =~ /^i(.*)/) { -+ $filename_inc=$1; -+ open(INCSRC,"<$filename_inc") or die "Cannot open $filename_inc.\n"; -+ while (<INCSRC>) { -+ print DST $_; -+ } -+ next; -+ } -+ if ($cmd_line =~ /^I/) { -+ print DST $saved_line; -+ next; -+ } -+} -+file_end(); -+close(CMD); -diff -Nur linux-mips-cvs/fs/jffs2/jffs2_bbc_armlib_comp.c linux-mips/fs/jffs2/jffs2_bbc_armlib_comp.c ---- linux-mips-cvs/fs/jffs2/jffs2_bbc_armlib_comp.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-mips/fs/jffs2/jffs2_bbc_armlib_comp.c 2005-02-07 05:08:34.000000000 +0100 -@@ -0,0 +1,2224 @@ -+/* -+ * JFFS2-BBC: armlib compressor plugin -+ * -+ * $Id: 301-jffs-compression,v 1.1 2005/03/26 10:33:31 wbx Exp $ -+ * -+ * Copyright (C) 2004, Ferenc Havasi & Tamas Gergely -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version 2 -+ * of the License, or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -+ * -+ */ -+ -+#include "jffs2_bbc_framework.h" -+ -+#ifdef __KERNEL__ -+#include <linux/string.h> -+#else -+#include <string.h> -+#endif -+ -+//ORIGIN: include/DataStructures/TypeDefs.h -+ -+/******************************************************************************* -+* FILE: TypeDefs.h -+* AUTHOR: Tamás Gergely -+* MODIFIED: $Id: 301-jffs-compression,v 1.1 2005/03/26 10:33:31 wbx Exp $ -+*******************************************************************************/ -+ -+#ifndef TYPEDEFS_H -+#define TYPEDEFS_H -+ -+#pragma pack(4) -+ -+#ifndef bool -+#define bool char -+#define true 1 -+#define false 0 -+#endif -+ -+#ifndef u8 -+#define u8 unsigned char -+#endif -+#ifndef u16 -+#define u16 unsigned short -+#endif -+#ifndef u32 -+#define u32 unsigned long -+#endif -+#ifndef s8 -+#define s8 signed char -+#endif -+#ifndef s16 -+#define s16 signed short -+#endif -+#ifndef s32 -+#define s32 signed long -+#endif -+ -+typedef struct -+{ -+ u32 capacity; -+ u32 size; -+ u32 alloc_size; -+ void *ptr; -+} vector; -+ -+#define VECTOR_P_END(vct) ((void*)(((char*)((vct)->ptr)) + (vct)->size)) -+#define VECTOR_S_END(vct) ((void*)(((char*)((vct).ptr)) + (vct).size)) -+ -+static void vector_clear(vector *); -+#ifdef JFFS2_BBC_ARMLIB_MODELGEN -+static void vector_reset(vector *); -+static void vector_clr_ptr(vector *); -+static void vector_add_u8(vector *, u8); -+static void vector_add_u16(vector *, u16); -+static void vector_add_u32(vector *, u32); -+static void vector_add_s8(vector *, s8); -+static void vector_add_s16(vector *, s16); -+static void vector_add_s32(vector *, s32); -+static void vector_add_ptr(vector *, void *); -+static void vector_concat(vector *, vector *); -+#endif -+ -+#endif -+ -+//ORIGIN: include/DataStructures/DataTypes.h -+ -+/******************************************************************************* -+* FILE: DataTypes.h -+* AUTHOR: Tamás Gergely -+* MODIFIED: $Id: 301-jffs-compression,v 1.1 2005/03/26 10:33:31 wbx Exp $ -+*******************************************************************************/ -+ -+#ifndef DATATYPES_H -+#define DATATYPES_H -+ -+//#include "DataStructures/TypeDefs.h" -+ -+typedef u16 THUMB_DataType; -+typedef u32 ARM_DataType; -+typedef u8 TokenType; -+typedef u8 PredictorType; -+typedef u8 *ProbDist; -+ -+typedef vector RawData; -+typedef vector RawBlocks; -+typedef vector TokenStream; -+typedef vector TokenBlocks; -+typedef vector LatType; -+ -+#define THUMB_DATA_LENGTH 16 -+#define ARM_DATA_LENGTH 32 -+#define TOKEN_LENGTH 8 -+#define TOKEN_MAXVALUE 0xff -+#define PREDICTOR_LENGTH 8 -+#define PREDICTOR_MAXVALUE 0xff -+ -+#endif -+ -+//ORIGIN: include/DataStructures/BitVector.h -+ -+/******************************************************************************* -+* FILE: BitVector.h -+* AUTHOR: Tamás Gergely -+* MODIFIED: $Id: 301-jffs-compression,v 1.1 2005/03/26 10:33:31 wbx Exp $ -+*******************************************************************************/ -+ -+#ifndef BITVECTOR_H -+#define BITVECTOR_H -+ -+//#include "DataStructures/TypeDefs.h" -+ -+typedef vector BitBlocks; -+ -+#pragma pack(4) -+ -+typedef struct -+{ -+ u32 freebits; -+ u32 capacity; -+ u32 size; -+ u8 *base; -+ u8 *ptr; -+} BitVector; -+ -+#ifdef JFFS2_BBC_ARMLIB_MODELGEN -+static void bitblocks_clear(BitBlocks *); -+static void bitvector_clear(BitVector *); -+static void bitvector_W_reset(BitVector *); -+static void bitvector_W_add0(BitVector *); -+static void bitvector_W_add1(BitVector *); -+static void bitvector_W_concat_b(BitVector *, BitVector *); -+static void bitvector_W_concat_v(BitVector *, vector *); -+static void bitvector_W_flush(BitVector *); -+static void bitvector_R_reset(BitVector *); -+static u8 bitvector_R_get1(BitVector *); -+static u8 bitvector_R_get8(BitVector *); -+#endif -+ -+#define BITVECTOR_P_END(bv) ((void*)(((bv)->base)+((bv)->size))) -+#define BITVECTOR_S_END(bv) ((void*)( ((bv).base)+ ((bv).size))) -+#define BITVECTOR_SKIP(bv,num) ((bv)->ptr) += (num) -+ -+#endif -+ -+//ORIGIN: include/DataStructures/DecisionTree.h -+ -+/******************************************************************************* -+* FILE: DecisionTree.h -+* AUTHOR: Tamás Gergely -+* MODIFIED: $Id: 301-jffs-compression,v 1.1 2005/03/26 10:33:31 wbx Exp $ -+*******************************************************************************/ -+ -+#ifndef DECISIONTREE_H -+#define DECISIONTREE_H -+ -+//#include "DataStructures/DataTypes.h" -+ -+#pragma pack(4) -+ -+#define TREENODETYPE_NULLNODE 0 -+#define TREENODETYPE_NODE_BINARY_EQ 1 -+#define TREENODETYPE_LEAF_P 2 -+#define TREENODETYPE_LEAF_C 3 -+#define TREENODETYPE_NODE_BINARY_LT 5 -+#define TREENODETYPE_IS_NODE(n) (((n) == TREENODETYPE_NODE_BINARY_EQ) || \ -+ ((n) == TREENODETYPE_NODE_BINARY_LT)) -+#define TREENODETYPE_IS_NODE_BINARY(n) (((n) == TREENODETYPE_NODE_BINARY_EQ) || \ -+ ((n) == TREENODETYPE_NODE_BINARY_LT)) -+ -+#define TREENODETYPE_IS_LEAF(n) (((n) == TREENODETYPE_LEAF_P) || \ -+ ((n) == TREENODETYPE_LEAF_C)) -+ -+ -+#define TREE_SUBTREE_RELATION_LEFT_EQ != -+#define TREE_SUBTREE_RELATION_RIGHT_EQ == -+#define TREE_SUBTREE_RELATION_LEFT_LT < -+#define TREE_SUBTREE_RELATION_RIGHT_LT >= -+ -+#define GET_NODE_PTR_TYPE(n) (((TreeNodeDummy*)(n))->type) -+ -+typedef struct -+{ -+ u8 type; -+} TreeNodeDummy; -+ -+typedef struct -+{ -+ u8 type; // [TREENODETYPE_NODE_BINARY] -+ u8 attribute; -+ PredictorType value; -+ void *left; -+ void *right; -+} TreeNodeBinary; -+ -+typedef struct -+{ -+ u8 type; // [TREENODETYPE_LEAF_P] -+ u16 pairs; -+ PredictorType *probabilities; -+} TreeLeafP; -+ -+typedef struct -+{ -+ u8 type; // [TREENODETYPE_LEAF_C] -+ PredictorType predicted_class; -+} TreeLeafC; -+ -+typedef struct -+{ -+ u32 high; -+ u32 low; -+ u32 max; -+} ProbabilityType; -+ -+ -+typedef struct -+{ -+ void *root; -+ u16 number_of_classes; -+ u16 number_of_predictors; -+ PredictorType *predictor_max_values; -+} DecisionTree; -+ -+#ifdef JFFS2_BBC_ARMLIB_MODELGEN -+static void decisiontree_delete(DecisionTree *); -+static void decisiontree_get_probability_for_token(void *, PredictorType *, TokenType, ProbabilityType *); -+static TokenType decisiontree_get_token_for_range(void *, PredictorType *, u32, u32, ProbabilityType *); -+#endif -+ -+#endif -+ -+//ORIGIN: include/DataStructures/PredictorTable.h -+ -+/******************************************************************************* -+* FILE: PredictorTable.h -+* AUTHOR: Tamás Gergely -+* MODIFIED: $Id: 301-jffs-compression,v 1.1 2005/03/26 10:33:31 wbx Exp $ -+*******************************************************************************/ -+ -+#ifndef PREDICTORTABLE_H -+#define PREDICTORTABLE_H -+ -+//#include "DataStructures/TypeDefs.h" -+//#include "DataStructures/DataTypes.h" -+////#include "DataStructures/Filter.h" -+////#include "DataStructures/Converter.h" -+////#include "DataStructures/Manipulator.h" -+ -+#define NUMBER_OF_PREDICTORS_ARM 17 -+ -+#ifndef __KERNEL__ -+#define NUMBER_OF_PREDICTORS_TXT 2 -+#else -+#undef TXT_TOKENS -+#endif // __KERNEL__ -+ -+#ifdef TXT_TOKENS -+#define NUMBER_OF_PREDICTORS NUMBER_OF_PREDICTORS_TXT -+#define predictortable_reset predictortable_resetTXT -+#define predictortable_update predictortable_updateTXT -+#define predictortable_minvalue predictortable_minvalueTXT -+#define predictortable_maxvalue predictortable_maxvalueTXT -+#else -+#define NUMBER_OF_PREDICTORS NUMBER_OF_PREDICTORS_ARM -+#define predictortable_reset predictortable_resetARM -+#define predictortable_update predictortable_updateARM -+#define predictortable_minvalue predictortable_minvalueARM -+#define predictortable_maxvalue predictortable_maxvalueARM -+#endif -+ -+ -+#pragma pack(4) -+ -+typedef struct -+{ -+ PredictorType *predictors; -+} PredictorTable; -+ -+#ifdef JFFS2_BBC_ARMLIB_MODELGEN -+static void predictortable_clear(PredictorTable *); -+static void predictortable_free(PredictorTable *); -+static void predictortable_resetARM(PredictorTable *); -+static void predictortable_updateARM(PredictorTable *, TokenType); -+static PredictorType predictortable_minvalueARM(PredictorTable *, u32); -+static PredictorType predictortable_maxvalueARM(PredictorTable *, u32); -+#endif -+ -+#ifndef __KERNEL__ -+/* -+static void predictortable_resetTXT(PredictorTable *); -+static void predictortable_updateTXT(PredictorTable *, TokenType); -+static PredictorType predictortable_minvalueTXT(PredictorTable *, u32); -+static PredictorType predictortable_maxvalueTXT(PredictorTable *, u32); -+*/ -+#endif // __KERNEL__ -+ -+#endif -+ -+//ORIGIN: include/DataStructures/ipack_model.h -+ -+/******************************************************************************* -+* FILE: ipack_model.h -+* AUTHOR: Tamás Gergely -+* MODIFIED: $Id: 301-jffs-compression,v 1.1 2005/03/26 10:33:31 wbx Exp $ -+*******************************************************************************/ -+ -+#ifndef IPACK_MODEL_H -+#define IPACK_MODEL_H -+ -+//#include "DataStructures/DataTypes.h" -+//#include "DataStructures/DecisionTree.h" -+//#include "DataStructures/PredictorTable.h" -+ -+#define PROBABILITY_SHIFT 12 -+#define PROBABILITY_MAX 0x00001000l -+ -+#define NUMBER_OF_TOKENS_ARM 16 -+#define NUMBER_OF_TOKENS_PER_INSTRUCTION_ARM 8 -+ -+#ifndef __KERNEL__ -+#define NUMBER_OF_TOKENS_TXT 256 -+#define NUMBER_OF_TOKENS_PER_INSTRUCTION_TXT 4 -+#else -+#undef TXT_TOKENS -+#endif // __KERNEL__ -+ -+#ifdef TXT_TOKENS -+#define NUMBER_OF_TOKENS NUMBER_OF_TOKENS_TXT -+#define NUMBER_OF_TOKENS_PER_INSTRUCTION NUMBER_OF_TOKENS_PER_INSTRUCTION_TXT -+#else -+#define NUMBER_OF_TOKENS NUMBER_OF_TOKENS_ARM -+#define NUMBER_OF_TOKENS_PER_INSTRUCTION NUMBER_OF_TOKENS_PER_INSTRUCTION_ARM -+#endif -+ -+#pragma pack(4) -+ -+/* -+ Data structure of an internal node of the tree -+*/ -+typedef struct -+{ -+ PredictorType *attribute_ptr; -+ u32 value; // PredictorType -+ void *right_child_ptr; -+} ipack_treenodeBin; -+/* -+ Data structure of a leaf with probabilities -+*/ -+typedef struct -+{ -+ u16 probabilities[0]; // PredictorType[0] -+} ipack_treeleafP; -+/* -+ Data structure of a leaf with class prediction -+*/ -+typedef struct -+{ -+ PredictorType predicted_class; // PredictorType -+} ipack_treeleafC; -+/* -+ Possible data structures of a tree node -+*/ -+typedef union -+{ -+ ipack_treenodeBin nodeBin; -+ ipack_treeleafP leafP; -+ ipack_treeleafC leafC; -+} ipack_node_data; -+/* -+ Tree node -+*/ -+typedef struct -+{ -+ u32 type; // u8 -+ ipack_node_data data; // ipack_node_data -+} ipack_nodetype; -+/* -+ Nullnode -+*/ -+typedef struct -+{ -+ u32 type; -+ u16 probabilities[NUMBER_OF_TOKENS]; -+} ipack_nullnode; -+/* -+ Model for ipack project -+*/ -+typedef struct -+{ -+ char ID[4]; // char[4] -+ char block_sign[4]; // only the first 2 are used! -+ void *tree_root_ptr; // void* -+ void *tree_code; // generated ARM code -+ PredictorType *predictors_ptr; // PredictorType* -+ ipack_nullnode nullnode; -+} ipack_model_type; -+ -+typedef struct -+{ -+ u32 high; -+ u32 low; -+} ipack_probability_type; -+ -+ -+static void ipack_model_get_probability_for_token(ipack_nodetype *, TokenType, ipack_probability_type *); -+static TokenType ipack_model_get_token_for_range(ipack_nodetype *, u32, u32, ipack_probability_type *); -+/*void ipack_model_predictortable_reset (PredictorType*); -+void ipack_model_predictortable_update (PredictorType*, TokenType);*/ -+ -+#ifndef __KERNEL__ -+/*static void ipack_model_printinfo(ipack_model_type *); -+static void ipack_dumpmodel(void *);*/ -+#endif -+ -+#endif -+ -+//ORIGIN: include/Builders/PredictorGenerator.h -+ -+/******************************************************************************* -+* FILE: PredictorGenerator.h -+* AUTHOR: Tamás Gergely -+* MODIFIED: $Id: 301-jffs-compression,v 1.1 2005/03/26 10:33:31 wbx Exp $ -+*******************************************************************************/ -+ -+#ifndef PREDICTORGENERATOR_H -+#define PREDICTORGENERATOR_H -+ -+//#include "DataStructures.h" -+ -+#ifdef JFFS2_BBC_ARMLIB_MODELGEN -+static PredictorTable *predictorgenerator_generate(void); -+#endif -+ -+#endif -+ -+//ORIGIN: include/Builders/Coder.h -+ -+/******************************************************************************* -+* FILE: Coder.h -+* AUTHOR: Tamás Gergely -+* MODIFIED: $Id: 301-jffs-compression,v 1.1 2005/03/26 10:33:31 wbx Exp $ -+*******************************************************************************/ -+ -+#ifndef CODER_H -+#define CODER_H -+ -+#define CODER_VALUEBITS 16 -+#define CODER_VALUEMAX 0x00010000l -+#define CODER_VALUE3RD 0x0000c000l -+#define CODER_VALUEHLF 0x00008000l -+#define CODER_VALUE1ST 0x00004000l -+ -+#endif -+ -+//ORIGIN: DataStructures/src/TypeDefs.c -+ -+/******************************************************************************* -+* FILE: TypeDefs.c -+* AUTHOR: Tamás Gergely -+* MODIFIED: $Id: 301-jffs-compression,v 1.1 2005/03/26 10:33:31 wbx Exp $ -+*******************************************************************************/ -+ -+//#include "ipack_common.h" -+//#include "DataStructures/TypeDefs.h" -+#ifndef __KERNEL__ -+#include <memory.h> -+#endif -+ -+#define VECTOR_ALLOC_SIZE 0x00001000 -+ -+static void vector_clear(vector * vct) -+{ -+ if (vct->ptr) -+ jffs2_bbc_free(vct->ptr); -+ vct->capacity = 0; -+ vct->size = 0; -+ vct->ptr = 0; -+} -+ -+#ifdef JFFS2_BBC_ARMLIB_MODELGEN -+static void vector_extend(vector * vct) -+{ -+ void *tmp; -+ vct->capacity += vct->alloc_size; -+ tmp = jffs2_bbc_malloc(vct->capacity); -+ if (vct->ptr) { -+ memcpy(tmp, vct->ptr, vct->size); -+ jffs2_bbc_free(vct->ptr); -+ } -+ vct->ptr = tmp; -+} -+ -+static void vector_reset(vector * vct) -+{ -+ vct->capacity = 0; -+ vct->size = 0; -+ vct->alloc_size = VECTOR_ALLOC_SIZE; -+ vct->ptr = 0; -+} -+ -+static void vector_clr_ptr(vector * vct) -+{ -+ void **it; -+ void *end_it; -+ for (it = vct->ptr, end_it = (((char *) (vct->ptr)) + vct->size); it != end_it; it++) { -+ vector_clear(*it); -+ jffs2_bbc_free(*it); -+ } -+ if (vct->ptr) -+ jffs2_bbc_free(vct->ptr); -+ vct->capacity = 0; -+ vct->size = 0; -+ vct->ptr = 0; -+} -+ -+static void vector_add_u8(vector * vct, u8 val) -+{ -+ if ((vct->size) + sizeof(u8) > (vct->capacity)) { -+ vector_extend(vct); -+ } -+ *(u8 *) ((char *) (vct->ptr) + (vct->size)) = val; -+ vct->size += sizeof(u8); -+}; -+ -+static void vector_add_u16(vector * vct, u16 val) -+{ -+ if ((vct->size) + sizeof(u16) > (vct->capacity)) { -+ vector_extend(vct); -+ } -+ *(u16 *) ((char *) (vct->ptr) + (vct->size)) = val; -+ vct->size += sizeof(u16); -+}; -+ -+static void vector_add_u32(vector * vct, u32 val) -+{ -+ if ((vct->size) + sizeof(u32) > (vct->capacity)) { -+ vector_extend(vct); -+ } -+ *(u32 *) ((char *) (vct->ptr) + (vct->size)) = val; -+ vct->size += sizeof(u32); -+}; -+ -+static void vector_add_s8(vector * vct, s8 val) -+{ -+ if ((vct->size) + sizeof(s8) > (vct->capacity)) { -+ vector_extend(vct); -+ } -+ *(s8 *) ((char *) (vct->ptr) + (vct->size)) = val; -+ vct->size += sizeof(s8); -+}; -+ -+static void vector_add_s16(vector * vct, s16 val) -+{ -+ if ((vct->size) + sizeof(s16) > (vct->capacity)) { -+ vector_extend(vct); -+ } -+ *(s16 *) ((char *) (vct->ptr) + (vct->size)) = val; -+ vct->size += sizeof(s16); -+}; -+ -+static void vector_add_s32(vector * vct, s32 val) -+{ -+ if ((vct->size) + sizeof(s32) > (vct->capacity)) { -+ vector_extend(vct); -+ } -+ *(s32 *) ((char *) (vct->ptr) + (vct->size)) = val; -+ vct->size += sizeof(s32); -+}; -+ -+static void vector_add_ptr(vector * vct, void *ptr) -+{ -+ if ((vct->size) + sizeof(void *) > (vct->capacity)) { -+ vector_extend(vct); -+ } -+ *(void **) ((char *) (vct->ptr) + (vct->size)) = ptr; -+ vct->size += sizeof(void *); -+} -+ -+static void vector_concat(vector * lhs, vector * rhs) -+{ -+ void *tmp; -+ if (!(rhs->size)) { -+ return; -+ } -+ tmp = lhs->ptr; -+ lhs->capacity = (lhs->size) + (rhs->size); -+ lhs->ptr = jffs2_bbc_malloc(lhs->capacity); -+ if (tmp) { -+ memcpy(lhs->ptr, tmp, lhs->size); -+ jffs2_bbc_free(tmp); -+ } -+ memcpy((((u8 *) lhs->ptr) + lhs->size), rhs->ptr, rhs->size); -+ lhs->size += rhs->size; -+} -+ -+#endif -+ -+//ORIGIN: DataStructures/src/BitVector.c -+ -+/******************************************************************************* -+* FILE: BitVector.c -+* AUTHOR: Tamás Gergely -+* MODIFIED: $Id: 301-jffs-compression,v 1.1 2005/03/26 10:33:31 wbx Exp $ -+*******************************************************************************/ -+ -+//#include "ipack_common.h" -+//#include "DataStructures/BitVector.h" -+#ifndef __KERNEL__ -+#include <memory.h> -+#endif -+ -+#define VECTOR_ALLOC_SIZE 0x00001000 -+ -+#ifdef JFFS2_BBC_ARMLIB_MODELGEN -+ -+static void bitblocks_clear(BitBlocks * this) -+{ -+ BitVector **it; -+ void *end_it; -+ for (it = this->ptr, end_it = VECTOR_P_END(this); it != end_it; it++) { -+ bitvector_clear(*it); -+ jffs2_bbc_free(*it); -+ } -+ jffs2_bbc_free(this->ptr); -+ this->ptr = 0; -+} -+ -+static void bitvector_clear(BitVector * this) -+{ -+ if (this->base) { -+ jffs2_bbc_free(this->base); -+ } -+ this->freebits = 0; -+ this->capacity = 0; -+ this->size = 0; -+ this->base = 0; -+ this->ptr = 0; -+} -+ -+static void bitvector_W_reset(BitVector * this) -+{ -+ this->freebits = 0; -+ this->capacity = 0; -+ this->size = 0; -+ this->base = 0; -+ this->ptr = 0; -+} -+ -+static void bitvector_W_add0(BitVector * this) -+{ -+ if (!(this->freebits)) { -+ if (this->size == this->capacity) { -+ void *tmp = this->base; -+ this->capacity += VECTOR_ALLOC_SIZE; -+ this->base = jffs2_bbc_malloc(this->capacity); -+ this->ptr = ((u8 *) (this->base)) + this->size; -+ memcpy(this->base, tmp, this->size); -+ jffs2_bbc_free(tmp); -+ } -+ else { -+ this->ptr++; -+ } -+ this->size++; -+ this->freebits = 7; -+ *(this->ptr) = 0x00; -+ } -+ else { -+ this->freebits--; -+ (*(this->ptr)) <<= 1; -+ } -+} -+ -+static void bitvector_W_add1(BitVector * this) -+{ -+ if (!(this->freebits)) { -+ if (this->size == this->capacity) { -+ void *tmp = this->base; -+ this->capacity += VECTOR_ALLOC_SIZE; -+ this->base = jffs2_bbc_malloc(this->capacity); -+ this->ptr = ((u8 *) (this->base)) + this->size; -+ memcpy(this->base, tmp, this->size); -+ jffs2_bbc_free(tmp); -+ } -+ else { -+ this->ptr++; -+ } -+ this->size++; -+ this->freebits = 7; -+ *(this->ptr) = 0x01; -+ } -+ else { -+ this->freebits--; -+ (*(this->ptr)) <<= 1; -+ (*(this->ptr)) |= 0x01; -+ } -+} -+ -+static void bitvector_W_concat_b(BitVector * lhs, BitVector * rhs) -+{ -+ void *tmp; -+ if (!(rhs->size)) { -+ return; -+ } -+ tmp = lhs->base; -+ lhs->capacity = ((((lhs->size) + (rhs->size) - 1) / VECTOR_ALLOC_SIZE) + 1) * VECTOR_ALLOC_SIZE; -+ lhs->base = jffs2_bbc_malloc(lhs->capacity); -+ if (tmp) { -+ memcpy(lhs->base, tmp, lhs->size); -+ jffs2_bbc_free(tmp); -+ } -+ memcpy((((u8 *) (lhs->base)) + lhs->size), rhs->base, rhs->size); -+ lhs->freebits = 0; -+ lhs->size += rhs->size; -+ lhs->ptr = ((u8 *) (lhs->base)) + lhs->size; -+} -+ -+static void bitvector_W_concat_v(BitVector * lhs, vector * rhs) -+{ -+ void *tmp; -+ if (!(rhs->size)) { -+ return; -+ } -+ tmp = lhs->base; -+ lhs->capacity = ((((lhs->size) + (rhs->size) - 1) / VECTOR_ALLOC_SIZE) + 1) * VECTOR_ALLOC_SIZE; -+ lhs->base = jffs2_bbc_malloc(lhs->capacity); -+ if (tmp) { -+ memcpy(lhs->base, tmp, lhs->size); -+ jffs2_bbc_free(tmp); -+ } -+ memcpy((((u8 *) (lhs->base)) + lhs->size), rhs->ptr, rhs->size); -+ lhs->freebits = 0; -+ lhs->size += rhs->size; -+ lhs->ptr = ((u8 *) (lhs->base)) + lhs->size; -+} -+ -+static void bitvector_W_flush(BitVector * this) -+{ -+ (*(this->ptr)) <<= this->freebits; -+ this->freebits = 0; -+} -+ -+static void bitvector_R_reset(BitVector * this) -+{ -+ this->freebits = 7; -+ this->ptr = this->base; -+} -+ -+static u8 bitvector_R_get1(BitVector * this) -+{ -+ u8 tmp = ((*(this->ptr)) >> this->freebits) & 0x01; -+ if (!(this->freebits)) { -+ this->freebits = 7; -+ this->ptr++; -+ } -+ else { -+ this->freebits--; -+ } -+ return tmp; -+} -+ -+static u8 bitvector_R_get8(BitVector * this) -+{ -+ u8 tmp = (*(this->ptr)); -+ this->ptr++; -+ return tmp; -+} -+ -+#endif -+ -+//ORIGIN: DataStructures/src/DecisionTree.c -+ -+/******************************************************************************* -+* FILE: DecisionTree.c -+* AUTHOR: Tamás Gergely -+* MODIFIED: $Id: 301-jffs-compression,v 1.1 2005/03/26 10:33:31 wbx Exp $ -+*******************************************************************************/ -+ -+//#include "ipack_common.h" -+//#include "DataStructures/DecisionTree.h" -+ -+static void decisiontree_delete_node(void *root) -+{ -+ u8 tmp = GET_NODE_PTR_TYPE(root); -+ if (TREENODETYPE_IS_NODE_BINARY(tmp)) { -+ decisiontree_delete_node(((TreeNodeBinary *) root)->left); -+ decisiontree_delete_node(((TreeNodeBinary *) root)->right); -+ } -+ else if ((tmp) == TREENODETYPE_LEAF_P) { -+ if (((TreeLeafP *) root)->probabilities) { -+ jffs2_bbc_free(((TreeLeafP *) root)->probabilities); -+ } -+ } -+ else if ((tmp) == TREENODETYPE_LEAF_C) { -+ } -+ jffs2_bbc_free(root); -+} -+ -+#ifdef JFFS2_BBC_ARMLIB_MODELGEN -+ -+static void decisiontree_delete(DecisionTree * dt) -+{ -+ decisiontree_delete_node(dt->root); -+ jffs2_bbc_free(dt->predictor_max_values); -+} -+ -+static void decisiontree_get_probability_for_token(void *root, PredictorType * preds, TokenType token, ProbabilityType * prob) -+{ -+ void *tmp = root; -+ while (TREENODETYPE_IS_NODE(((TreeNodeBinary *) tmp)->type)) { -+ if (((TreeNodeBinary *) tmp)->type == TREENODETYPE_NODE_BINARY_EQ) { -+ if (preds[((TreeNodeBinary *) tmp)->attribute] TREE_SUBTREE_RELATION_LEFT_EQ((TreeNodeBinary *) tmp)->value) { -+ tmp = ((TreeNodeBinary *) tmp)->left; -+ } -+ else { -+ tmp = ((TreeNodeBinary *) tmp)->right; -+ } -+ } -+ else if (((TreeNodeBinary *) tmp)->type == TREENODETYPE_NODE_BINARY_LT) { -+ if (preds[((TreeNodeBinary *) tmp)->attribute] TREE_SUBTREE_RELATION_LEFT_LT((TreeNodeBinary *) tmp)->value) { -+ tmp = ((TreeNodeBinary *) tmp)->left; -+ } -+ else { -+ tmp = ((TreeNodeBinary *) tmp)->right; -+ } -+ } -+ } -+ prob->high = 0; -+ prob->low = 0; -+ prob->max = 0; -+ if (((TreeNodeBinary *) tmp)->type == TREENODETYPE_LEAF_P) { -+ u32 i; -+ u32 lngth = ((TreeLeafP *) tmp)->pairs << 1; -+ for (i = 0; i < lngth;) { -+ TokenType at = ((TreeLeafP *) tmp)->probabilities[i++]; -+ TokenType av = ((TreeLeafP *) tmp)->probabilities[i++]; -+ if (token > at) -+ prob->low += av; -+ if (token >= at) -+ prob->high += av; -+ prob->max += av; -+ } -+ } -+ else if (((TreeNodeBinary *) tmp)->type == TREENODETYPE_LEAF_C) { -+ if (((TreeLeafC *) tmp)->predicted_class == token) { -+ prob->high = TOKEN_MAXVALUE; -+ prob->max = TOKEN_MAXVALUE; -+ } -+ } -+} -+ -+static TokenType decisiontree_get_token_for_range(void *root, PredictorType * preds, u32 value, u32 range, ProbabilityType * prob) -+{ -+ void *tmp = root; -+ TokenType token = 0; -+ while (TREENODETYPE_IS_NODE(((TreeNodeBinary *) tmp)->type)) { -+ if (((TreeNodeBinary *) tmp)->type == TREENODETYPE_NODE_BINARY_EQ) { -+ if (preds[((TreeNodeBinary *) tmp)->attribute] TREE_SUBTREE_RELATION_LEFT_EQ((TreeNodeBinary *) tmp)->value) { -+ tmp = ((TreeNodeBinary *) tmp)->left; -+ } -+ else { -+ tmp = ((TreeNodeBinary *) tmp)->right; -+ } -+ } -+ else if (((TreeNodeBinary *) tmp)->type == TREENODETYPE_NODE_BINARY_LT) { -+ if (preds[((TreeNodeBinary *) tmp)->attribute] TREE_SUBTREE_RELATION_LEFT_LT((TreeNodeBinary *) tmp)->value) { -+ tmp = ((TreeNodeBinary *) tmp)->left; -+ } -+ else { -+ tmp = ((TreeNodeBinary *) tmp)->right; -+ } -+ } -+ } -+ prob->high = 0; -+ prob->low = 0; -+ prob->max = 0; -+ if (((TreeNodeBinary *) tmp)->type == TREENODETYPE_LEAF_P) { -+ u32 i; -+ u32 norm; -+ TokenType at = 0; -+ TokenType av; -+ u32 lngth = ((TreeLeafP *) tmp)->pairs << 1; -+ for (i = 0; i < lngth;) { -+ i++; -+ prob->max += ((TreeLeafP *) tmp)->probabilities[i++]; -+ } -+ norm = (value * prob->max - 1) / range; -+ for (i = 0; prob->high <= norm;) { -+ at = ((TreeLeafP *) tmp)->probabilities[i++]; -+ av = ((TreeLeafP *) tmp)->probabilities[i++]; -+ prob->high += av; -+ if (prob->high <= norm) -+ prob->low += av; -+ } -+ token = at; -+ } -+ else if (((TreeNodeBinary *) tmp)->type == TREENODETYPE_LEAF_C) { -+ token = ((TreeLeafC *) tmp)->predicted_class; -+ prob->high = TOKEN_MAXVALUE; -+ prob->max = TOKEN_MAXVALUE; -+ } -+ return token; -+} -+#endif -+ -+//ORIGIN: DataStructures/src/PredictorTable.c -+ -+/******************************************************************************* -+* FILE: PredictorTable.c -+* AUTHOR: Tamás Gergely -+* MODIFIED: $Id: 301-jffs-compression,v 1.1 2005/03/26 10:33:31 wbx Exp $ -+*******************************************************************************/ -+ -+//#include "ipack_common.h" -+//#include "DataStructures/PredictorTable.h" -+ -+#ifdef JFFS2_BBC_ARMLIB_MODELGEN -+ -+static void predictortable_clear(PredictorTable * table) -+{ -+ table->predictors = 0; -+} -+ -+static void predictortable_free(PredictorTable * table) -+{ -+ if (table->predictors) { -+ jffs2_bbc_free(table->predictors); -+ table->predictors = 0; -+ } -+} -+ -+static void predictortable_resetARM(PredictorTable * table) -+{ -+ register PredictorType *ptr = table->predictors; -+ register PredictorType *end = ptr + NUMBER_OF_PREDICTORS_ARM; -+ while (ptr < end) { -+ *(ptr++) = 0; -+ } -+} -+ -+static void predictortable_updateARM(PredictorTable * table, TokenType token) -+{ -+ register PredictorType *ptr = table->predictors; -+ register u32 ndx = ptr[0] + 1; -+ ptr[ndx + 8] = ptr[ndx]; -+ ptr[ndx] = token; -+ if (ndx == 8) { -+ ptr[0] = 0; -+ } -+ else { -+ ++ptr[0]; -+ } -+} -+ -+static PredictorType predictortable_minvalueARM(PredictorTable * table, u32 index) -+{ -+ return 0; -+} -+ -+static PredictorType predictortable_maxvalueARM(PredictorTable * table, u32 index) -+{ -+ if (index == 0) { -+ return 7; -+ } -+ else { -+ return 15; -+ } -+} -+ -+#endif -+ -+#ifndef __KERNEL__ -+ -+/*static void predictortable_resetTXT(PredictorTable * table) -+{ -+ register PredictorType *ptr = table->predictors; -+ register PredictorType *end = ptr + NUMBER_OF_PREDICTORS_TXT; -+ while (ptr < end) { -+ *(ptr++) = 0; -+ } -+} -+ -+static void predictortable_updateTXT(PredictorTable * table, TokenType token) -+{ //TODO: modify -+ register PredictorType *ptr = table->predictors; -+// register u32 ndx; -+ ptr[0] = token; -+ if ((('a' <= token) && (token <= 'z')) || (('A' <= token) && (token <= 'Z'))) { -+ ++(ptr[1]); -+ } -+ else { -+ ptr[1] = 0; -+ } -+} -+ -+static PredictorType predictortable_minvalueTXT(PredictorTable * table, u32 index) -+{ -+ return 0; -+} -+ -+static PredictorType predictortable_maxvalueTXT(PredictorTable * table, u32 index) -+{ //TODO: modify -+ return 254; -+}*/ -+ -+#endif // __KERNEL__ -+ -+//ORIGIN: DataStructures/src/ipack_model.c -+ -+/******************************************************************************* -+* FILE: ipack_model.c -+* AUTHOR: Tamás Gergely -+* MODIFIED: $Id: 301-jffs-compression,v 1.1 2005/03/26 10:33:31 wbx Exp $ -+*******************************************************************************/ -+ -+//#include "DataStructures/ipack_model.h" -+//#include "measuredef.h" -+//#include "ipack_common.h" -+ -+#ifdef __MEASURE_TIME_MODEL_GETPROB -+#define __MT_P_MAX 256 -+#define __MT_P_DIV 128 -+#define __MT_P_MIN 0 -+#endif -+ -+static void ipack_model_get_probability_for_token(ipack_nodetype * tmp, TokenType token, ipack_probability_type * prob) -+{ -+// register ipack_nodetype* tmp = model->tree_root_ptr; -+// register ipack_nodetype* tmp = root; -+ while (TREENODETYPE_IS_NODE(tmp->type)) { -+ if (tmp->type == TREENODETYPE_NODE_BINARY_EQ) { -+ if (*(tmp->data.nodeBin.attribute_ptr) TREE_SUBTREE_RELATION_LEFT_EQ tmp->data.nodeBin.value) { -+ ((char *) tmp) += sizeof(tmp->type) + sizeof(ipack_treenodeBin); -+ } -+ else { -+ tmp = tmp->data.nodeBin.right_child_ptr; -+ } -+ } -+ else if (tmp->type == TREENODETYPE_NODE_BINARY_LT) { -+ if (*(tmp->data.nodeBin.attribute_ptr) TREE_SUBTREE_RELATION_LEFT_LT tmp->data.nodeBin.value) { -+ ((char *) tmp) += sizeof(tmp->type) + sizeof(ipack_treenodeBin); -+ } -+ else { -+ tmp = tmp->data.nodeBin.right_child_ptr; -+ } -+ } -+ } -+ prob->high = 0; -+ prob->low = 0; -+// prob->max = 0; -+ if (tmp->type == TREENODETYPE_LEAF_P) { -+ if (token) { -+ prob->low = tmp->data.leafP.probabilities[token - 1]; -+ } -+ prob->high = tmp->data.leafP.probabilities[token]; -+// prob->max = tmp->data.leafP.probabilities[15]; -+ } -+ else if (tmp->type == TREENODETYPE_LEAF_C) { -+ if (tmp->data.leafC.predicted_class == token) { -+ prob->high = TOKEN_MAXVALUE; -+// prob->max = TOKEN_MAXVALUE; -+ } -+ } -+} -+ -+#ifndef IPACK_ARM_ASM -+ -+//return ipack_model_get_token_for_range2(tmp,value,range,prob); -+ -+static TokenType ipack_model_get_token_for_range(ipack_nodetype * tmp, u32 value, u32 range, ipack_probability_type * prob) -+{ -+// register ipack_nodetype* tmp = model->tree_root_ptr; -+// register ipack_nodetype* tmp = root; -+ register TokenType token = 0; -+ while (TREENODETYPE_IS_NODE(tmp->type)) { -+ if (tmp->type == TREENODETYPE_NODE_BINARY_EQ) { -+ if (*(tmp->data.nodeBin.attribute_ptr) TREE_SUBTREE_RELATION_LEFT_EQ tmp->data.nodeBin.value) { -+ ((char *) tmp) += sizeof(tmp->type) + sizeof(ipack_treenodeBin); -+ } -+ else { -+ tmp = tmp->data.nodeBin.right_child_ptr; -+ } -+ } -+ else if (tmp->type == TREENODETYPE_NODE_BINARY_LT) { -+ if (*(tmp->data.nodeBin.attribute_ptr) TREE_SUBTREE_RELATION_LEFT_LT tmp->data.nodeBin.value) { -+ ((char *) tmp) += sizeof(tmp->type) + sizeof(ipack_treenodeBin); -+ } -+ else { -+ tmp = tmp->data.nodeBin.right_child_ptr; -+ } -+ } -+ } -+ prob->high = 0; -+ prob->low = 0; -+// prob->max = 0; -+ if (tmp->type == TREENODETYPE_LEAF_P) { -+ u32 i; -+ u32 norm; -+// prob->max = tmp->data.leafP.probabilities[15]; -+/* norm = (value * prob->max -1)/range; -+ for(i = 0; i < 15; ++i) { -+ if(tmp->data.leafP.probabilities[i] > norm) { -+ break; -+ } -+ }*/ -+ norm = ((value << PROBABILITY_SHIFT) - 1); -+ for (i = 0; i < NUMBER_OF_TOKENS; ++i) { -+ if (range * tmp->data.leafP.probabilities[i] > norm) { -+ break; -+ } -+ } -+ token = (TokenType) i; -+ prob->high = tmp->data.leafP.probabilities[i]; -+ if (token) { -+ prob->low = tmp->data.leafP.probabilities[token - 1]; -+ } -+ } -+ else if (tmp->type == TREENODETYPE_LEAF_C) { -+ token = tmp->data.leafC.predicted_class; -+ prob->high = PROBABILITY_MAX; -+// prob->max = PROBABILITY_MAX; -+ } -+ return token; -+} -+#endif -+/* -+void ipack_model_predictortable_reset(PredictorType* ptr) -+{ -+// register PredictorType* ptr = model->predictors_ptr; -+// register PredictorType* ptr = preds; -+ register PredictorType* end = ptr + NUMBER_OF_PREDICTORS; -+ while(ptr < end) { -+ *(ptr++) = 0; -+ } -+} -+ -+void ipack_model_predictortable_update(PredictorType* ptr, TokenType token) -+{ -+// register PredictorType* ptr = model->predictors_ptr; -+// register PredictorType* ptr = preds; -+ register u32 ndx = ptr[0] + 1; -+ ptr[ndx + 8] = ptr[ndx]; -+ ptr[ndx] = token; -+ if(ndx == 8) { -+ ptr[0] = 0; -+ } else { -+ ++ ptr[0]; -+ } -+}*/ -+/****************************************************************************/ -+ -+#ifndef __KERNEL__ -+static void ipack_model_countpreds(void *ptr, ipack_nodetype * node, double *table, double val) -+{ -+ if ((node->type == TREENODETYPE_NODE_BINARY_EQ) || (node->type == TREENODETYPE_NODE_BINARY_LT)) { -+ table[(u32) (node->data.nodeBin.attribute_ptr) - (u32) (ptr)] += val; -+ ipack_model_countpreds(ptr, (void *) (((u8 *) (node)) + sizeof(node->type) + sizeof(ipack_treenodeBin)), table, val / 2); -+ ipack_model_countpreds(ptr, node->data.nodeBin.right_child_ptr, table, val / 2); -+ } -+ else { -+ } -+} -+ -+/*static void ipack_model_printinfo(ipack_model_type * model) -+{ -+ double *prcnt = jffs2_bbc_malloc(sizeof(double) * NUMBER_OF_PREDICTORS); -+ u32 i; -+ for (i = 0; i < NUMBER_OF_PREDICTORS; i++) { -+ prcnt[i] = 0.0; -+ } -+ ipack_model_countpreds(model->predictors_ptr, model->tree_root_ptr, prcnt, 100); -+ for (i = 0; i < NUMBER_OF_PREDICTORS; i++) { -+ jffs2_bbc_print3(" p[%3d] = %10.6lf\n", (int) i, prcnt[i]); -+ } -+ jffs2_bbc_free(prcnt); -+}*/ -+ -+static void ipack_dumpnode(unsigned char **ptr, FILE * file, char *prefs) -+{ -+ switch (*((*ptr)++)) { -+ u32 i; -+ u32 j; -+ u32 x; -+ u32 y; -+ case TREENODETYPE_NODE_BINARY_EQ: -+ x = *((*ptr)++); -+ y = *((*ptr)++); -+ fprintf(file, "%s+->\tBinary node: P[%u] equals %u\n", prefs, (unsigned int)x, (unsigned int)y); -+ for (j = 0; j < 4096 && prefs[j]; ++j); -+ prefs[j] = '\t'; -+ prefs[++j] = '|'; -+ ipack_dumpnode(ptr, file, prefs); -+ prefs[j--] = 0; -+ ipack_dumpnode(ptr, file, prefs); -+ prefs[j] = 0; -+ break; -+ case TREENODETYPE_NODE_BINARY_LT: -+ x = *((*ptr)++); -+ y = *((*ptr)++); -+ fprintf(file, "%s+->\tBinary node: P[%u] greater than %u\n", prefs, (unsigned int)x, (unsigned int)y); -+ for (j = 0; j < 4096 && prefs[j]; ++j); -+ prefs[j] = '\t'; -+ prefs[++j] = '|'; -+ ipack_dumpnode(ptr, file, prefs); -+ prefs[j--] = 0; -+ ipack_dumpnode(ptr, file, prefs); -+ prefs[j] = 0; -+ break; -+ case TREENODETYPE_LEAF_P: -+ x = *((*ptr)++); -+ fprintf(file, "%s+->\tLeaf: %u pairs\n", prefs, (unsigned int)x); -+ (*ptr) += (x << 1); -+ break; -+ case TREENODETYPE_LEAF_C: -+ x = *((*ptr)++); -+ fprintf(file, "%s+->\tLeaf: class %u\n", prefs, (unsigned int)x); -+ break; -+ default: -+ fprintf(file, "%s+->\tLeaf: nullnode\n", prefs); -+ } -+} -+ -+/*static void ipack_dumpmodel(void *model) -+{ -+ unsigned char *tmp_ptr = model; -+ FILE *file; -+ char C[4096]; -+ if ((file = fopen("DUMPED_MODEL", "wa"))) { -+ int i; -+ for (i = 0; i < 4096; C[i++] = 0); -+ tmp_ptr += 8; -+ tmp_ptr += sizeof(u32); -+ ipack_dumpnode(&tmp_ptr, file, C); -+ fclose(file); -+ } -+}*/ -+ -+#endif -+ -+//ORIGIN: Builders/src/PredictorGenerator.c -+ -+/******************************************************************************* -+* FILE: PredictorGenerator.c -+* AUTHOR: Tamás Gergely -+* MODIFIED: $Id: 301-jffs-compression,v 1.1 2005/03/26 10:33:31 wbx Exp $ -+*******************************************************************************/ -+ -+//#include "ipack_common.h" -+//#include "Builders/PredictorGenerator.h" -+ -+#ifdef JFFS2_BBC_ARMLIB_MODELGEN -+static PredictorTable *predictorgenerator_generate( /*PredictorGeneratorSettings* settings */ ) -+{ -+ PredictorTable *ptr = jffs2_bbc_malloc(sizeof(PredictorTable)); -+ predictortable_clear(ptr); -+ ptr->predictors = jffs2_bbc_malloc(NUMBER_OF_PREDICTORS * sizeof(PredictorType)); -+ return ptr; -+} -+#endif -+ -+//ORIGIN: Builders/src/ipack_armlib_compressor.c -+ -+/******************************************************************************* -+* FILE: ipack_armlim_compressor.c -+* AUTHOR: Tamás Gergely -+* MODIFIED: $Id: 301-jffs-compression,v 1.1 2005/03/26 10:33:31 wbx Exp $ -+*******************************************************************************/ -+ -+//#include "ipack_common.h" -+//#include "DataStructures.h" -+//#include "Builders/PredictorGenerator.h" -+//#include "Builders/Tokenizer.h" -+//#include "Builders/Coder.h" -+ -+#define EC_NO_ERROR 0 -+#define EC_NOT_IPMF_FILE -1 -+#define EC_NOT_IPMF_MODEL -2 -+#define EC_NOT_HG_BLOCK -3 -+#define EC_WRONG_INPUT_LENGTH -501 -+#define EC_CODER_WRONG_PROBABILITY 1 -+#define EC_CODER_WRONG_RANGE 2 -+#define EC_BUFFER_OVERFLOW 501 -+#define EC_BUFFER_UNDERFLOW 502 -+#define EC_UNKNOWN_TOKEN_TYPE 1001 -+#define EC_UNKNOWN_FILTER 1002 -+#define EC_UNKNOWN_CONVERTER 1003 -+#define EC_UNKNOWN_MANIPULATOR 1004 -+ -+/******************************************************************************* -+ -+ COMPRESSOR INIT FUNCTIONS -+ -+*******************************************************************************/ -+ -+#define ROUND_UP_TO_DWORD(val) ( ( (val) + 3 ) & 0xfffffffc ) -+ -+#ifndef __KERNEL__ -+int ipack_glb_endian_X; -+#endif -+ -+static int ipack_compressor_init_tree(unsigned char **ptr, ipack_model_type * model, ipack_nodetype * node, void *nullnode) -+{ -+ int retval = 0; -+ node->type = *((*ptr)++); -+ switch (node->type) { -+ u32 i; -+ u32 j; -+ u32 lngth; -+ u32 tmpret; -+ TokenType at; -+ u16 av; -+ case TREENODETYPE_NODE_BINARY_EQ: -+ case TREENODETYPE_NODE_BINARY_LT: -+ node->data.nodeBin.attribute_ptr = (model->predictors_ptr) + (*((*ptr)++)); -+ node->data.nodeBin.value = *((*ptr)++); -+ retval = sizeof(node->data.nodeBin); -+ retval += ipack_compressor_init_tree(ptr, model, (void *) ROUND_UP_TO_DWORD(((u32) node) + sizeof(node->type) + sizeof(node->data.nodeBin)), nullnode); -+ node->data.nodeBin.right_child_ptr = (void *) ROUND_UP_TO_DWORD(((u32) node) + retval + sizeof(node->type)); -+ retval += ipack_compressor_init_tree(ptr, model, node->data.nodeBin.right_child_ptr, nullnode); -+ break; -+ case TREENODETYPE_LEAF_P: -+ lngth = *((*ptr)++); -+ av = 0; -+ for (i = 0, j = 0; i < lngth; ++i) { -+ at = *((*ptr)++); -+ while (j < at) { -+ node->data.leafP.probabilities[j++] = av; -+ } -+ av += *((*ptr)++); -+ } -+ while (j < NUMBER_OF_TOKENS) { -+ node->data.leafP.probabilities[j++] = av; -+ } -+ for (i = 0; i < NUMBER_OF_TOKENS; ++i) { -+ node->data.leafP.probabilities[i] = ((node->data.leafP.probabilities[i] << PROBABILITY_SHIFT) / node->data.leafP.probabilities[NUMBER_OF_TOKENS - 1]); -+ } -+ retval = ROUND_UP_TO_DWORD(NUMBER_OF_TOKENS * sizeof(u16)); -+ break; -+ case TREENODETYPE_LEAF_C: -+ node->data.leafC.predicted_class = *((*ptr)++); -+ retval = sizeof(node->data.leafC); -+ retval = ROUND_UP_TO_DWORD(retval); -+ break; -+ default: -+ return 0; -+ } -+ return retval + sizeof(node->type); -+} -+ -+#define IPACK_TREE_CONVERT_REPLACE 0 -+#define IPACK_TREE_CONVERT_KEEP 1 -+ -+static void *ipack_tree_to_code(ipack_model_type * model, int *code_size); -+ -+static int ipack_armlib_convert_tree_to_code(ipack_model_type * model_img, int mode) -+{ -+#ifdef IPACK_TREE_TO_CODE -+ int tree_size; -+ -+ model_img->tree_code = ipack_tree_to_code(model_img, &tree_size); -+ jffs2_bbc_print2("Convertation done. Code size=%d\n", tree_size); -+ if (mode == IPACK_TREE_CONVERT_REPLACE) { -+ jffs2_bbc_print1("Freeing original tree.\n"); -+ jffs2_bbc_free(model_img->tree_root_ptr); -+ model_img->tree_root_ptr = NULL; -+ } -+#endif -+ return 0; -+} -+ -+ -+static int ipack_armlib_compressor_init(void **model) -+{ -+ int retval = EC_NO_ERROR; -+ unsigned char *tmp_ptr = *model; -+ u32 i; -+ ipack_model_type *model_img; -+ char tmp_c[2]; -+ -+ if (*(tmp_ptr++) != 'i') { -+ return EC_NOT_IPMF_FILE; -+ } -+ else if (*(tmp_ptr++) != 'P') { -+ return EC_NOT_IPMF_FILE; -+ } -+ else if (*(tmp_ptr++) != 'M') { -+ return EC_NOT_IPMF_FILE; -+ } -+ else if (*(tmp_ptr++) != 'F') { -+ return EC_NOT_IPMF_FILE; -+ } -+ tmp_c[0] = *(tmp_ptr++); -+ tmp_c[1] = *(tmp_ptr++); -+ tmp_ptr += 2; -+ -+ //model_img = jffs2_bbc_malloc(*((u32*)tmp_ptr)); -+ model_img = jffs2_bbc_malloc(sizeof(ipack_model_type) + ROUND_UP_TO_DWORD(NUMBER_OF_PREDICTORS)); -+ model_img->tree_root_ptr = jffs2_bbc_malloc(*((u32 *) tmp_ptr)); //it is smaller a little but, but... -+ -+ tmp_ptr += sizeof(u32); -+ -+ model_img->ID[0] = 'i'; -+ model_img->ID[1] = 'P'; -+ model_img->ID[2] = 'M'; -+ model_img->ID[3] = 'F'; -+ -+ model_img->block_sign[0] = tmp_c[0]; -+ model_img->block_sign[1] = tmp_c[1]; -+ -+ model_img->nullnode.type = TREENODETYPE_LEAF_P; -+ for (i = 0; i < NUMBER_OF_TOKENS; ++i) { -+ model_img->nullnode.probabilities[i] = 0; -+ } -+ model_img->predictors_ptr = (void *) (((u32) model_img) + sizeof(ipack_model_type)); -+ //model_img->tree_root_ptr = (void*)ROUND_UP_TO_DWORD(((u32)(model_img->predictors_ptr)) + NUMBER_OF_PREDICTORS);//ALIGN -+ -+ ipack_compressor_init_tree(&tmp_ptr, model_img, model_img->tree_root_ptr, &(model_img->nullnode)); -+ -+#ifdef IPACK_TREE_TO_CODE -+#ifdef IPACK_AUTO_TREE_TO_CODE -+ jffs2_bbc_print1("Automatically converting tree to ARM code...\n"); -+ ipack_armlib_convert_tree_to_code(model_img, IPACK_TREE_CONVERT_REPLACE); -+#else -+ model_img->tree_code = NULL; -+#endif -+#else -+ model_img->tree_code = NULL; -+#endif -+ -+ jffs2_bbc_free(*model); -+ *model = model_img; -+ return retval; -+} -+ -+/******************************************************************************* -+ -+ COMPRESSOR DEINIT FUNCTIONS -+ -+*******************************************************************************/ -+ -+ -+/* Descructor of compressor (model will be freed with jffs2_bbc_free() after it)*/ -+static void ipack_armlib_compressor_deinit(void) -+{ -+} -+ -+/******************************************************************************* -+ -+ COMPRESS FUNCTIONS -+ -+*******************************************************************************/ -+ -+static int writebits0(unsigned char **dest, u8 * freebits, u32 * opposite, unsigned char *end) -+{ -+ if (!(*freebits)) { -+ ++(*dest); -+ *freebits = 7; -+ **dest = 0x00; -+ } -+ else { -+ --(*freebits); -+ (**dest) <<= 1; -+ } -+ if ((*dest == end) && !(*freebits)) { -+ return EC_BUFFER_OVERFLOW; -+ } -+ while (*opposite) { -+ --(*opposite); -+ if (!(*freebits)) { -+ ++(*dest); -+ *freebits = 7; -+ **dest = 0x01; -+ } -+ else { -+ --(*freebits); -+ (**dest) <<= 1; -+ (**dest) |= 0x01; -+ } -+ if ((*dest == end) && !(*freebits)) { -+ return EC_BUFFER_OVERFLOW; -+ } -+ } -+ return 0; -+} -+ -+static int writebits1(unsigned char **dest, u8 * freebits, u32 * opposite, unsigned char *end) -+{ -+ if (!(*freebits)) { -+ ++(*dest); -+ *freebits = 7; -+ **dest = 0x01; -+ } -+ else { -+ --(*freebits); -+ (**dest) <<= 1; -+ (**dest) |= 0x01; -+ } -+ if ((*dest == end) && !(*freebits)) { -+ return EC_BUFFER_OVERFLOW; -+ } -+ while (*opposite) { -+ --(*opposite); -+ if (!(*freebits)) { -+ ++(*dest); -+ *freebits = 7; -+ **dest = 0x00; -+ } -+ else { -+ --(*freebits); -+ (**dest) <<= 1; -+ } -+ if ((*dest == end) && !(*freebits)) { -+ return EC_BUFFER_OVERFLOW; -+ } -+ } -+ return 0; -+} -+ -+ -+ -+ -+/* Compress block -+ * *dstlen bytes are allocated. -+ * if it is not enough write *sourcelen over to the processed amount of data -+ * returns non zero if fails -+ */ -+static int ipack_armlib_compress(void *model, unsigned char *input, unsigned char *output, unsigned long *sourcelen, unsigned long *dstlen) -+{ -+ register u32 coder_high = CODER_VALUEMAX - 1; -+ register u32 coder_low = 0; -+ u32 coder_opbits = 0; -+ u8 bitvector_freebits = 8; -+ unsigned char *bitvector_ptr = output; -+ unsigned char *bitvector_end = output + (*dstlen - 1); -+ ARM_DataType *tmpp; -+ TokenStream tmpv; -+ TokenType *it; -+ void *end_it; -+ -+ ipack_nodetype *treeroot = ((ipack_model_type *) model)->tree_root_ptr; -+ PredictorType *predctrs = ((ipack_model_type *) model)->predictors_ptr; -+ -+#ifdef IPACK_TREE_TO_CODE -+ void (*treefunc) (ipack_nodetype *, TokenType, ipack_probability_type *); -+ -+ treefunc = ((ipack_model_type *) model)->tree_code; -+ if (treefunc != NULL) -+ treefunc += 4; -+#endif -+ -+ if ((*sourcelen % 4) != 0) { -+ return EC_WRONG_INPUT_LENGTH; -+ } -+ if (*dstlen <= 4) { -+ return EC_BUFFER_OVERFLOW; -+ } -+ -+ if (((ipack_model_type *) model)->ID[0] != 'i') { -+ return EC_NOT_IPMF_MODEL; -+ } -+ else if (((ipack_model_type *) model)->ID[1] != 'P') { -+ return EC_NOT_IPMF_MODEL; -+ } -+ else if (((ipack_model_type *) model)->ID[2] != 'M') { -+ return EC_NOT_IPMF_MODEL; -+ } -+ else if (((ipack_model_type *) model)->ID[3] != 'F') { -+ return EC_NOT_IPMF_MODEL; -+ } -+#ifdef TXT_TOKENS -+ tmpv.capacity = (*sourcelen); -+#else -+ tmpv.capacity = (*sourcelen) << 1; -+#endif -+ tmpv.size = tmpv.capacity; -+ tmpv.ptr = jffs2_bbc_malloc(tmpv.size); -+ it = tmpv.ptr; -+ -+#ifndef __KERNEL__ -+ if (ipack_glb_endian_X) { -+ for (tmpp = (void *) input; (u32) tmpp < (u32) (input + *sourcelen); ++tmpp) { -+#ifdef TXT_TOKENS -+ *(it++) = (u8) ((*tmpp & 0xff000000) >> 24); -+ *(it++) = (u8) ((*tmpp & 0x00ff0000) >> 16); -+ *(it++) = (u8) ((*tmpp & 0x0000ff00) >> 8); -+ *(it++) = (u8) ((*tmpp & 0x000000ff)); -+#else -+ *(it++) = (u8) ((*tmpp & 0x0000f000) >> 12); -+ *(it++) = (u8) ((*tmpp & 0x0000000f)); -+ *(it++) = (u8) ((*tmpp & 0xf0000000) >> 28); -+ *(it++) = (u8) ((*tmpp & 0x000f0000) >> 16); -+ *(it++) = (u8) ((*tmpp & 0x00000f00) >> 8); -+ *(it++) = (u8) ((*tmpp & 0x00f00000) >> 20); -+ *(it++) = (u8) ((*tmpp & 0x0f000000) >> 24); -+ *(it++) = (u8) ((*tmpp & 0x000000f0) >> 4); -+#endif //TXT_TOKENS -+ } -+ } -+ else { -+#endif -+ for (tmpp = (void *) input; (u32) tmpp < (u32) (input + *sourcelen); ++tmpp) { -+#ifdef TXT_TOKENS -+ *(it++) = (u8) ((*tmpp & 0x000000ff)); -+ *(it++) = (u8) ((*tmpp & 0x0000ff00) >> 8); -+ *(it++) = (u8) ((*tmpp & 0x00ff0000) >> 16); -+ *(it++) = (u8) ((*tmpp & 0xff000000) >> 24); -+#else -+ *(it++) = (u8) ((*tmpp & 0x00f00000) >> 20); -+ *(it++) = (u8) ((*tmpp & 0x0f000000) >> 24); -+ *(it++) = (u8) ((*tmpp & 0x000000f0) >> 4); -+ *(it++) = (u8) ((*tmpp & 0x00000f00) >> 8); -+ *(it++) = (u8) ((*tmpp & 0x000f0000) >> 16); -+ *(it++) = (u8) ((*tmpp & 0x0000f000) >> 12); -+ *(it++) = (u8) ((*tmpp & 0x0000000f)); -+ *(it++) = (u8) ((*tmpp & 0xf0000000) >> 28); -+#endif //TXT_TOKENS -+ } -+#ifndef __KERNEL__ -+ } -+#endif -+/* -+ ENCODE -+*/ -+ { //predictor reset -+ register PredictorType *ptr = predctrs; -+ register PredictorType *end = ptr + NUMBER_OF_PREDICTORS; -+ while (ptr < end) { -+ *(ptr++) = 0; -+ } -+ } -+ -+ //*(bitvector_ptr++) = 'H'; -+ //*(bitvector_ptr++) = 'G'; -+ *(bitvector_ptr++) = ((ipack_model_type *) model)->block_sign[0]; -+ *(bitvector_ptr++) = ((ipack_model_type *) model)->block_sign[1]; -+ -+ *(bitvector_ptr++) = (unsigned char) (((*sourcelen) >> 8) & 0xff); -+ *(bitvector_ptr++) = (unsigned char) ((*sourcelen) & 0xff); -+ for (it = tmpv.ptr, end_it = VECTOR_S_END(tmpv); it != end_it; ++it) { -+ ipack_probability_type prob; -+ u32 range; -+ -+#ifdef IPACK_TREE_TO_CODE -+ if (treefunc != NULL) -+ (*treefunc) (treeroot, *it, &prob); -+ else -+ ipack_model_get_probability_for_token(treeroot, *it, &prob); -+#else -+ ipack_model_get_probability_for_token(treeroot, *it, &prob); -+#endif -+ -+ if (prob.high == prob.low) { -+ vector_clear(&tmpv); -+ return EC_CODER_WRONG_PROBABILITY; -+ } -+ range = coder_high - coder_low + 1; -+ coder_high = coder_low + ((range * prob.high) >> PROBABILITY_SHIFT) - 1; -+ coder_low += ((range * prob.low) >> PROBABILITY_SHIFT); -+ for (;;) { -+ if (coder_high < CODER_VALUEHLF) { -+ if (writebits0(&bitvector_ptr, &bitvector_freebits, &coder_opbits, bitvector_end)) { -+ vector_clear(&tmpv); -+ return EC_BUFFER_OVERFLOW; -+ } -+ } -+ else if (coder_low >= CODER_VALUEHLF) { -+ if (writebits1(&bitvector_ptr, &bitvector_freebits, &coder_opbits, bitvector_end)) { -+ vector_clear(&tmpv); -+ return EC_BUFFER_OVERFLOW; -+ } -+ coder_high -= CODER_VALUEHLF; -+ coder_low -= CODER_VALUEHLF; -+ } -+ else if ((CODER_VALUE1ST <= coder_low) && (coder_high < CODER_VALUE3RD)) { -+ ++coder_opbits; -+ coder_high -= CODER_VALUE1ST; -+ coder_low -= CODER_VALUE1ST; -+ } -+ else { -+ break; -+ } -+ coder_high <<= 1; -+ ++coder_high; -+ coder_low <<= 1; -+ if (coder_high < coder_low) { -+ vector_clear(&tmpv); -+ return EC_CODER_WRONG_RANGE; -+ } -+ } -+ { -+#ifdef TXT_TOKENS -+// register u32 ndx; -+ predctrs[0] = *it; -+ if ((('a' <= *it) && (*it <= 'z')) || (('A' <= *it) && (*it <= 'Z'))) { -+ ++(predctrs[1]); -+ } -+ else { -+ predctrs[1] = 0; -+ } -+#else -+ register u32 ndx = predctrs[0] + 1; -+ predctrs[ndx + 8] = predctrs[ndx]; -+ predctrs[ndx] = *it; -+ if (ndx == 8) { -+ predctrs[0] = 0; -+ } -+ else { -+ ++predctrs[0]; -+ } -+#endif -+ } -+ -+ } -+ vector_clear(&tmpv); -+ ++coder_opbits; -+ if (coder_low < CODER_VALUE1ST) { -+ if (writebits0(&bitvector_ptr, &bitvector_freebits, &coder_opbits, bitvector_end)) { -+ return EC_BUFFER_OVERFLOW; -+ } -+ } -+ else { -+ if (writebits1(&bitvector_ptr, &bitvector_freebits, &coder_opbits, bitvector_end)) { -+ return EC_BUFFER_OVERFLOW; -+ } -+ } -+ (*(bitvector_ptr)) <<= bitvector_freebits; -+ *dstlen = ((u32) bitvector_ptr - (u32) output + 1); -+ return EC_NO_ERROR; -+} -+ -+/******************************************************************************* -+ -+ DECOMPRESS FUNCTIONS -+ -+*******************************************************************************/ -+ -+typedef struct -+{ -+ u32 high; -+ u32 low; -+ u32 value; -+ u32 overread; -+} ipack_decompressor_values; -+ -+typedef struct -+{ -+ u8 freebits; -+ unsigned char *ptr; -+ unsigned char *end; -+} ipack_decompressor_bitvector; -+ -+static u8 ipack_bitvector_R_get1(ipack_decompressor_bitvector * bv) -+{ -+ u8 tmp; -+ if (bv->ptr == bv->end) { -+ bv->freebits = 0; -+ return 0; -+ } -+ tmp = (*(bv->ptr) >> bv->freebits) & 0x01; -+ if (!(bv->freebits)) { -+ bv->freebits = 7; -+ ++(bv->ptr); -+ } -+ else { -+ --(bv->freebits); -+ } -+ return tmp; -+} -+ -+/* Decompress block -+ * returns non zero if fails -+ */ -+static int ipack_armlib_decompress(void *model, unsigned char *input, unsigned char *output, unsigned long sourcelen, unsigned long dstlen) -+{ -+ ARM_DataType *data; -+ register u32 coder_high = CODER_VALUEMAX - 1; -+ register u32 coder_low = 0; -+ register u32 coder_value = 0; -+ u32 coder_overread = 0; -+ ipack_decompressor_bitvector bitvector; -+ u32 lngth; -+ u32 i; -+ u32 cntbytes; -+ TokenType tkns[8]; -+ TokenType *tptr; -+ -+ ipack_nodetype *treeroot = ((ipack_model_type *) model)->tree_root_ptr; -+ PredictorType *predctrs = ((ipack_model_type *) model)->predictors_ptr; -+ -+#ifdef IPACK_TREE_TO_CODE -+ TokenType(*treefunc) (ipack_nodetype *, u32, u32, ipack_probability_type *); -+ -+ treefunc = ((ipack_model_type *) model)->tree_code; -+#endif -+ -+ -+ if (((ipack_model_type *) model)->ID[0] != 'i') { -+ return EC_NOT_IPMF_MODEL; -+ } -+ else if (((ipack_model_type *) model)->ID[1] != 'P') { -+ return EC_NOT_IPMF_MODEL; -+ } -+ else if (((ipack_model_type *) model)->ID[2] != 'M') { -+ return EC_NOT_IPMF_MODEL; -+ } -+ else if (((ipack_model_type *) model)->ID[3] != 'F') { -+ return EC_NOT_IPMF_MODEL; -+ } -+ -+ bitvector.freebits = 7; -+ bitvector.ptr = input; -+ bitvector.end = input + sourcelen; -+ -+ /*if(*(bitvector.ptr++) != 'H') { -+ return EC_NOT_HG_BLOCK; -+ } else if(*(bitvector.ptr++) != 'G') { -+ return EC_NOT_HG_BLOCK; -+ } */ -+ bitvector.ptr++; -+ bitvector.ptr++; -+ -+ data = (void *) output; -+ cntbytes = *(bitvector.ptr++); -+ cntbytes <<= 8; -+ cntbytes += *(bitvector.ptr++); -+ -+ { //predictor reset -+ register PredictorType *ptr = predctrs; -+ register PredictorType *end = ptr + NUMBER_OF_PREDICTORS; -+ while (ptr < end) { -+ *(ptr++) = 0; -+ } -+ } -+ for (i = 0; i < CODER_VALUEBITS; ++i) { -+ coder_value <<= 1; -+ coder_value += ipack_bitvector_R_get1(&bitvector); -+ } -+ lngth = dstlen >> 2; -+ if (lngth > (cntbytes >> 2)) { -+ lngth = cntbytes >> 2; -+ } -+ for (i = 0; (i < lngth); ++i) { -+ TokenType itoken; -+ u32 j; -+ tptr = tkns; -+ for (j = 0; j < NUMBER_OF_TOKENS_PER_INSTRUCTION; ++j) { -+ ipack_probability_type prob; -+ u32 range = coder_high - coder_low + 1; -+ -+#ifdef IPACK_TREE_TO_CODE -+ if (treefunc != NULL) -+ itoken = (*treefunc) (treeroot, coder_value - coder_low + 1, range, &prob); -+ else -+#endif -+ itoken = ipack_model_get_token_for_range(treeroot, coder_value - coder_low + 1, range, &prob); -+ -+ -+ if (prob.high == prob.low) { -+ return EC_CODER_WRONG_PROBABILITY; -+ } -+ coder_high = coder_low + ((range * prob.high) >> PROBABILITY_SHIFT) - 1; -+ coder_low += ((range * prob.low) >> PROBABILITY_SHIFT); -+ for (;;) { -+ if (coder_high < CODER_VALUEHLF) { -+ } -+ else if (CODER_VALUEHLF <= coder_low) { -+ coder_value -= CODER_VALUEHLF; -+ coder_high -= CODER_VALUEHLF; -+ coder_low -= CODER_VALUEHLF; -+ } -+ else if ((CODER_VALUE1ST <= coder_low) && (coder_high < CODER_VALUE3RD)) { -+ coder_value -= CODER_VALUE1ST; -+ coder_high -= CODER_VALUE1ST; -+ coder_low -= CODER_VALUE1ST; -+ } -+ else { -+ break; -+ } -+ coder_low <<= 1; -+ coder_high <<= 1; -+ ++(coder_high); -+ coder_value <<= 1; -+ if (bitvector.ptr == bitvector.end) { -+ bitvector.freebits = 0; -+ } -+ coder_value += ((*(bitvector.ptr) >> bitvector.freebits) & 0x01); -+ if (bitvector.freebits) { -+ --bitvector.freebits; -+ } -+ else { -+ bitvector.freebits = 7; -+ ++bitvector.ptr; -+ } -+ if (coder_high < coder_low) { -+ return EC_CODER_WRONG_RANGE; -+ } -+ if ((bitvector.ptr == bitvector.end) && !(bitvector.freebits)) { -+ if ((coder_overread++) > CODER_VALUEBITS) { -+ return EC_BUFFER_UNDERFLOW; -+ } -+ } -+ } -+ { -+#ifdef TXT_TOKENS -+// register u32 ndx; -+ predctrs[0] = itoken; -+ if ((('a' <= itoken) && (itoken <= 'z')) || (('A' <= itoken) && (itoken <= 'Z'))) { -+ ++(predctrs[1]); -+ } -+ else { -+ predctrs[1] = 0; -+ } -+ -+#else -+ register u32 ndx = predctrs[0] + 1; -+ predctrs[ndx + 8] = predctrs[ndx]; -+ predctrs[ndx] = itoken; -+ if (ndx == 8) { -+ predctrs[0] = 0; -+ } -+ else { -+ ++predctrs[0]; -+ } -+#endif -+ } -+ -+ (*(tptr++)) = itoken; -+ } -+ tptr = tkns; -+#ifndef __KERNEL__ -+ if (ipack_glb_endian_X) { -+#ifdef TXT_TOKENS -+ (*data) = ((*tptr) << 24); -+ ++tptr; -+ (*data) |= ((*tptr) << 16); -+ ++tptr; -+ (*data) |= ((*tptr) << 8); -+ ++tptr; -+ (*data) |= (*tptr); -+ ++data; -+#else -+ (*data) = (((*tptr) & 0xf) << 12); -+ ++tptr; -+ (*data) |= ((*tptr) & 0xf); -+ ++tptr; -+ (*data) |= (((*tptr) & 0xf) << 28); -+ ++tptr; -+ (*data) |= (((*tptr) & 0xf) << 16); -+ ++tptr; -+ (*data) |= (((*tptr) & 0xf) << 8); -+ ++tptr; -+ (*data) |= (((*tptr) & 0xf) << 20); -+ ++tptr; -+ (*data) |= (((*tptr) & 0xf) << 24); -+ ++tptr; -+ (*data) |= (((*tptr) & 0xf) << 4); -+ ++data; -+#endif -+ } -+ else { -+#endif -+#ifdef TXT_TOKENS -+ (*data) = (*tptr); -+ ++tptr; -+ (*data) |= ((*tptr) << 8); -+ ++tptr; -+ (*data) |= ((*tptr) << 16); -+ ++tptr; -+ (*data) |= ((*tptr) << 24); -+ ++data; -+#else -+ (*data) = (((*tptr) & 0xf) << 20); -+ ++tptr; -+ (*data) |= (((*tptr) & 0xf) << 24); -+ ++tptr; -+ (*data) |= (((*tptr) & 0xf) << 4); -+ ++tptr; -+ (*data) |= (((*tptr) & 0xf) << 8); -+ ++tptr; -+ (*data) |= (((*tptr) & 0xf) << 16); -+ ++tptr; -+ (*data) |= (((*tptr) & 0xf) << 12); -+ ++tptr; -+ (*data) |= ((*tptr) & 0xf); -+ ++tptr; -+ (*data) |= (((*tptr) & 0xf) << 28); -+ ++data; -+#endif -+#ifndef __KERNEL__ -+ } -+#endif -+ } -+ return EC_NO_ERROR; -+} -+ -+static int ipack_armlib_estimate(void *model, unsigned char *input, unsigned long sourcelen, unsigned long *dstlen, unsigned long *readtime, unsigned long *writetime) -+{ -+ int i, tmp, tmp2, max, maxi; -+ int cnt_cond[] = { 0, 0, 0, 0 }; -+ int cnt_inst[] = { 0, 0, 0, 0 }; -+ -+ // TODO: make a more precise estimation!!! -+ *readtime = JFFS2_BBC_ZLIB_READ_TIME * 6; -+ *writetime = JFFS2_BBC_ZLIB_WRITE_TIME * 2; -+ -+ if (sourcelen % 4 != 0) { -+ *dstlen = sourcelen; -+ return 0; -+ } -+ for (i = 0; i < sourcelen; i++, input++) { -+ tmp2 = tmp = *input; -+ tmp = ((tmp) & 0xf0) >> 4; -+ tmp2 = tmp2 & 0xf; -+ if (tmp == 14) -+ cnt_cond[i % 4]++; -+ if ((tmp2 == 2) || (tmp2 == 3)) -+ cnt_inst[i % 4]++; -+ } -+ maxi = -1; -+ max = -1; -+ for (i = 0; i < 4; i++) -+ if (max < cnt_cond[i]) { -+ max = cnt_cond[i]; -+ maxi = i; -+ } -+ /*jffs2_bbc_print("armlib_EST: %d/%d : %d/%d %d/%d %d/%d %d/%d", -+ cnt_cond[maxi],cnt_inst[maxi], -+ cnt_cond[0],cnt_inst[0], -+ cnt_cond[1],cnt_inst[1], -+ cnt_cond[2],cnt_inst[2], -+ cnt_cond[3],cnt_inst[3]); */ -+ -+ if (cnt_cond[maxi] < (sourcelen >> 4)) { -+ *dstlen = sourcelen; -+ } -+ else { -+ *dstlen = sourcelen / 3; -+ } -+ -+ return 0; -+} -+ -+static char *ipack_armlib_proc_info(void); -+static int ipack_armlib_proc_command(char *command); -+static void ipack_armlib_destroy_model(void **model); -+ -+struct jffs2_bbc_compressor_type jffs2_bbc_armlib = { -+ "armlib", -+ 0x464d5069, -+ {0, 0, 0, 0}, -+ NULL, // init -+ ipack_armlib_compressor_init, // init_model -+ ipack_armlib_destroy_model, // destroy_model -+ ipack_armlib_compressor_deinit, // deinit -+ ipack_armlib_compress, -+ ipack_armlib_estimate, -+ ipack_armlib_decompress, -+ ipack_armlib_proc_info, -+ ipack_armlib_proc_command -+}; -+ -+ -+static char *ipack_armlib_proc_info() -+{ -+#ifdef IPACK_TREE_TO_CODE -+#ifdef IPACK_AUTO_TREE_TO_CODE -+ return "automatic tree to code conversion"; -+#else -+ return "manual tree to code conversion possibility"; -+#endif -+#else -+ return "tree in memory version"; -+#endif -+} -+ -+static int ipack_armlib_proc_command(char *command) -+{ -+ struct jffs2_bbc_model_list_node *model; -+ ipack_model_type *armlib_model; -+ -+ if ((*command == 'g') || (*command == 'G')) { -+ jffs2_bbc_print1("Converting tree(s) to ARM code... (keeping original)\n"); -+ model = jffs2_bbc_armlib.models; -+ if (model == NULL) -+ jffs2_bbc_print1("no model found!\n"); -+ while (model != NULL) { -+ armlib_model = model->model; -+ if (armlib_model == NULL) { -+ jffs2_bbc_print1("Error: NULL model!\n"); -+ } -+ else { -+ ipack_armlib_convert_tree_to_code(armlib_model, IPACK_TREE_CONVERT_KEEP); -+ } -+ model = model->next_compr_model; -+ } -+ } -+ else if ((*command == 'r') || (*command == 'R')) { -+ jffs2_bbc_print1("Converting tree(s) to ARM code... (deleting original)\n"); -+ model = jffs2_bbc_armlib.models; -+ if (model == NULL) -+ jffs2_bbc_print1("no model found!\n"); -+ while (model != NULL) { -+ armlib_model = model->model; -+ if (armlib_model == NULL) { -+ jffs2_bbc_print1("Error: NULL model!\n"); -+ } -+ else { -+ //armlib_model->tree_code = ipack_tree_to_code(armlib_model, &tree_size); -+ //jffs2_bbc_print("Convertation done. Code size=%d\n",tree_size); -+ ipack_armlib_convert_tree_to_code(armlib_model, IPACK_TREE_CONVERT_REPLACE); -+ } -+ model = model->next_compr_model; -+ } -+ } -+ else if ((*command == 'c') || (*command == 'C')) { -+ jffs2_bbc_print1("Deleting ARM representation of the tree(s)...\n"); -+ model = jffs2_bbc_armlib.models; -+ if (model == NULL) -+ jffs2_bbc_print1("no model found!\n"); -+ while (model != NULL) { -+ armlib_model = model->model; -+ if (armlib_model == NULL) { -+ jffs2_bbc_print1("Error: NULL model!\n"); -+ } -+ else { -+ if (armlib_model->tree_code == NULL) { -+ jffs2_bbc_print1("already deleted.\n"); -+ } -+ else { -+ if (armlib_model->tree_root_ptr == NULL) { -+ jffs2_bbc_print1("cannot delete this ARM tree - original tree has deleted\n"); -+ } -+ else { -+ jffs2_bbc_print1("deleting..."); -+ jffs2_bbc_free(armlib_model->tree_code); -+ armlib_model->tree_code = NULL; -+ jffs2_bbc_print1("done.\n"); -+ } -+ } -+ } -+ model = model->next_compr_model; -+ } -+ } -+ else if (*command == '?') { -+ jffs2_bbc_print1("ARMLIB commands:\n"); -+ jffs2_bbc_print1(" g: convert TREEs to ARM code and keep the original\n"); -+ jffs2_bbc_print1(" r: convert TREEs to ARM code and remove the original\n"); -+ jffs2_bbc_print1(" c: delete the original TREEs - if there is any\n"); -+ } -+ else { -+ jffs2_bbc_print1("Unknown command.\n"); -+ } -+ return 0; -+} -+ -+static void ipack_armlib_destroy_model(void **model) -+{ -+ ipack_model_type *model_img; -+ -+ model_img = *model; -+ if (model_img == NULL) { -+ jffs2_bbc_print1("jffs2.bbc: armlib: NULL model at destoying model!\n"); -+ return; -+ } -+ if (model_img->tree_code != NULL) { -+ //jffs2_bbc_print1("jffs2.bbc: armlib: debug: freeing code...\n"); -+ jffs2_bbc_free(model_img->tree_code); -+ model_img->tree_code = NULL; -+ } -+ if (model_img->tree_root_ptr != NULL) { -+ //jffs2_bbc_print1("jffs2.bbc: armlib: debug: freeing tree...\n"); -+ jffs2_bbc_free(model_img->tree_root_ptr); -+ model_img->tree_root_ptr = NULL; -+ } -+ -+ jffs2_bbc_free(model_img); -+ *model = NULL; -+} -+ -+struct jffs2_bbc_compressor_type *jffs2_bbc_armlib_init(int mode) -+{ -+ if (jffs2_bbc_register_compressor(&jffs2_bbc_armlib) == 0) -+ return &jffs2_bbc_armlib; -+ else -+ return NULL; -+} -+ -+void jffs2_bbc_armlib_deinit(void) -+{ -+ jffs2_bbc_unregister_compressor(&jffs2_bbc_armlib); -+} -+ -+/*END OF ARMLIB*/ -diff -Nur linux-mips-cvs/fs/jffs2/jffs2_bbc_framework.c linux-mips/fs/jffs2/jffs2_bbc_framework.c ---- linux-mips-cvs/fs/jffs2/jffs2_bbc_framework.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-mips/fs/jffs2/jffs2_bbc_framework.c 2005-02-07 05:08:34.000000000 +0100 -@@ -0,0 +1,1324 @@ -+/* -+ * JFFS2-BBC: Compression Framework -+ * -+ * $Id: 301-jffs-compression,v 1.1 2005/03/26 10:33:31 wbx Exp $ -+ * -+ * Copyright (C) 2004, Ferenc Havasi -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version 2 -+ * of the License, or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -+ * -+ */ -+ -+/* USE JFFS2_BBC_STANDALONE define if you don't want to compile without JFFS2 */ -+ -+//#define DEBUG_COMPRESSORS -+//#define DEBUG_SHOW_BLOCK_SIZES -+ -+#define JFFS2_BBC_STAT_BUFF_SIZE 8000 -+ -+#ifndef __KERNEL__ -+ -+#include <stdio.h> -+#include <malloc.h> -+typedef unsigned long uint32_t; -+ -+#else -+ -+#include <linux/kernel.h> -+#include <linux/slab.h> -+#include <linux/vmalloc.h> -+ -+#endif -+ -+#define JFFS2_BBC_ZLIB_BLOCK_SIGN_0 (120) -+#define JFFS2_BBC_ZLIB_BLOCK_SIGN_1 (94) -+ -+#define JFFS2_BBC_DUMMY_BLOCKSIGN_0 (0x54) -+#define JFFS2_BBC_DUMMY_BLOCKSIGN_1 (0x01) -+ -+#ifndef NULL -+#define NULL ((void*)(0)) -+#endif -+ -+#include "jffs2_bbc_framework.h" -+ -+/********************************************************************* -+ * Global data * -+ *********************************************************************/ -+ -+static int jffs2_bbc_compression_mode = JFFS2_BBC_ZLIB_MODE; -+static struct jffs2_bbc_compressor_type *jffs2_bbc_manual_compressor = NULL; -+static struct jffs2_bbc_compressor_type *jffs2_bbc_compressors = NULL; -+static struct jffs2_bbc_model_list_node *jffs2_bbc_model_list = NULL; -+static void *last_sb = NULL; /* previously activated sb */ -+ -+/********************************************************************* -+ * Compressor initialization * -+ *********************************************************************/ -+ -+#ifndef JFFS2_BBC_STANDALONE -+ -+#if !defined(__KERNEL__) || defined(CONFIG_JFFS2_BBC_ARMLIB) -+struct jffs2_bbc_compressor_type *jffs2_bbc_armlib_init(void); -+void jffs2_bbc_armlib_deinit(void); -+#endif -+ -+#if !defined(__KERNEL__) || defined(CONFIG_JFFS2_BBC_LZO) -+struct jffs2_bbc_compressor_type *jffs2_bbc_lzo_init(void); -+void jffs2_bbc_lzo_deinit(void); -+#endif -+ -+#if !defined(__KERNEL__) || defined(CONFIG_JFFS2_BBC_LZSS) -+struct jffs2_bbc_compressor_type *jffs2_bbc_lzss_init(void); -+void jffs2_bbc_lzss_deinit(void); -+#endif -+ -+#if !defined(__KERNEL__) || defined(CONFIG_JFFS2_BBC_LZARI) -+struct jffs2_bbc_compressor_type *jffs2_bbc_lzari_init(void); -+void jffs2_bbc_lzari_deinit(void); -+#endif -+ -+#if !defined(__KERNEL__) || defined(CONFIG_JFFS2_BBC_LZHD) -+struct jffs2_bbc_compressor_type *jffs2_bbc_lzhd_init(void); -+void jffs2_bbc_lzhd_deinit(void); -+#endif -+ -+void jffs2_bbc_compressor_init() -+{ -+#if !defined(__KERNEL__) || defined(CONFIG_JFFS2_BBC_ARMLIB) -+ jffs2_bbc_armlib_init(); -+#endif -+#if !defined(__KERNEL__) || defined(CONFIG_JFFS2_BBC_LZO) -+ jffs2_bbc_lzo_init(); -+#endif -+#if !defined(__KERNEL__) || defined(CONFIG_JFFS2_BBC_LZSS) -+ jffs2_bbc_lzss_init(); -+#endif -+#if !defined(__KERNEL__) || defined(CONFIG_JFFS2_BBC_LZARI) -+ jffs2_bbc_lzari_init(); -+#endif -+#if !defined(__KERNEL__) || defined(CONFIG_JFFS2_BBC_LZHD) -+ jffs2_bbc_lzhd_init(); -+#endif -+} -+ -+void jffs2_bbc_compressor_deinit() -+{ -+#if !defined(__KERNEL__) || defined(CONFIG_JFFS2_BBC_LZHD) -+ jffs2_bbc_lzhd_deinit(); -+#endif -+#if !defined(__KERNEL__) || defined(CONFIG_JFFS2_BBC_LZARI) -+ jffs2_bbc_lzari_deinit(); -+#endif -+#if !defined(__KERNEL__) || defined(CONFIG_JFFS2_BBC_LZSS) -+ jffs2_bbc_lzss_deinit(); -+#endif -+#if !defined(__KERNEL__) || defined(CONFIG_JFFS2_BBC_LZO) -+ jffs2_bbc_lzo_deinit(); -+#endif -+#if !defined(__KERNEL__) || defined(CONFIG_JFFS2_BBC_ARMLIB) -+ jffs2_bbc_armlib_deinit(); -+#endif -+} -+ -+#endif -+ -+#ifndef JFFS2_BBC_STANDALONE -+ -+/********************************************************************* -+ * ZLIB COMPRESSOR * -+ *********************************************************************/ -+ -+extern int jffs2_zlib_compress2(unsigned char *data_in, unsigned char *cpage_out, uint32_t * sourcelen, uint32_t * dstlen); -+extern void jffs2_zlib_decompress2(unsigned char *data_in, unsigned char *cpage_out, uint32_t srclen, uint32_t destlen); -+ -+static int jffs2_bbc_zlib_compress(void *model, unsigned char *input, unsigned char *output, unsigned long *sourcelen, unsigned long *dstlen) -+{ -+ return jffs2_zlib_compress2(input, output, sourcelen, dstlen); -+} -+ -+static int jffs2_bbc_zlib_decompress(void *model, unsigned char *input, unsigned char *output, unsigned long sourcelen, unsigned long dstlen) -+{ -+ jffs2_zlib_decompress2(input, output, sourcelen, dstlen); -+ return 0; -+} -+ -+static int jffs2_bbc_zlib_estimate(void *model, unsigned char *input, unsigned long sourcelen, unsigned long *dstlen, unsigned long *readtime, unsigned long *writetime) -+{ -+ *dstlen = sourcelen * 65 / 100; -+ *readtime = JFFS2_BBC_ZLIB_READ_TIME; -+ *writetime = JFFS2_BBC_ZLIB_WRITE_TIME; -+ return 0; -+} -+ -+static struct jffs2_bbc_compressor_type jffs2_bbc_zlib = { -+ "zlib", -+ 0, -+ {JFFS2_BBC_ZLIB_BLOCK_SIGN_0, JFFS2_BBC_ZLIB_BLOCK_SIGN_1, 0, 0}, -+ NULL, -+ NULL, -+ NULL, -+ NULL, -+ jffs2_bbc_zlib_compress, -+ jffs2_bbc_zlib_estimate, -+ jffs2_bbc_zlib_decompress, -+ NULL, -+ NULL, -+ 1 -+}; -+ -+static struct jffs2_bbc_compressor_type *jffs2_bbc_original_compressor = &jffs2_bbc_zlib; -+ -+#endif -+ -+/********************************************************************* -+ * Compression mode handling * -+ *********************************************************************/ -+ -+int jffs2_bbc_get_compression_mode(void) -+{ -+ return jffs2_bbc_compression_mode; -+} -+ -+void jffs2_bbc_set_compression_mode(int mode) -+{ -+ jffs2_bbc_compression_mode = mode; -+} -+ -+void jffs2_bbc_set_manual_compressor(struct jffs2_bbc_compressor_type *c) -+{ -+ jffs2_bbc_manual_compressor = c; -+ jffs2_bbc_set_compression_mode(JFFS2_BBC_MANUAL_MODE); -+} -+ -+int jffs2_bbc_set_manual_compressor_by_name(char *name) -+{ -+ struct jffs2_bbc_compressor_type *l; -+ int i; -+ -+ l = jffs2_bbc_compressors; -+ while (l != NULL) { -+ for (i = 0; i < 1000; i++) { -+ if (l->name[i] == 0) { -+ jffs2_bbc_set_manual_compressor(l); -+ return 0; -+ } -+ else if (name[i] == 0) -+ i = 1000; -+ else if (name[i] != l->name[i]) -+ i = 1000; -+ } -+ l = l->next; -+ } -+ jffs2_bbc_set_manual_compressor(NULL); -+ return 1; -+} -+ -+static struct jffs2_bbc_compressor_type *jffs2_bbc_get_compressor_by_name(char *name) -+{ -+ struct jffs2_bbc_compressor_type *l; -+ int i; -+ -+#ifndef JFFS2_BBC_STANDALONE -+ l = jffs2_bbc_original_compressor; -+ for (i = 0; i < 1000; i++) { -+ if (l->name[i] == 0) { -+ return l; -+ } -+ else if (name[i] == 0) -+ i = 1000; -+ else if (name[i] != l->name[i]) -+ i = 1000; -+ } -+#endif -+ -+ l = jffs2_bbc_compressors; -+ while (l != NULL) { -+ for (i = 0; i < 1000; i++) { -+ if (l->name[i] == 0) { -+ return l; -+ } -+ else if (name[i] == 0) -+ i = 1000; -+ else if (name[i] != l->name[i]) -+ i = 1000; -+ } -+ l = l->next; -+ } -+ -+ return NULL; -+} -+ -+int jffs2_bbc_disable_compressor_by_name(char *name) -+{ -+ struct jffs2_bbc_compressor_type *l; -+ -+ l = jffs2_bbc_get_compressor_by_name(name); -+ if (l == NULL) return 1; -+ l->enabled = 0; -+ return 0; -+} -+ -+int jffs2_bbc_enable_compressor_by_name(char *name) -+{ -+ struct jffs2_bbc_compressor_type *l; -+ -+ l = jffs2_bbc_get_compressor_by_name(name); -+ if (l == NULL) return 1; -+ l->enabled = 1; -+ return 0; -+} -+ -+void jffs2_bbc_compressor_command_by_name(char *name_and_command) -+{ -+ struct jffs2_bbc_compressor_type *l; -+ int i; -+ -+ l = jffs2_bbc_compressors; -+ while (l != NULL) { -+ for (i = 0; i < 1000; i++) { -+ if (l->name[i] == 0) { -+ if (name_and_command[i] != ':') { -+ jffs2_bbc_print1("jffs2.bbc: ':' missing after compressor name\n"); -+ } -+ else { -+ if (l->proc_command != NULL) -+ l->proc_command(name_and_command + i + 1); -+ } -+ i = 1000; -+ return; -+ } -+ else if (name_and_command[i] == 0) { -+ i = 1000; -+ } -+ else if (name_and_command[i] != l->name[i]) { -+ i = 1000; -+ } -+ } -+ l = l->next; -+ } -+} -+ -+struct jffs2_bbc_compressor_type *jffs2_bbc_get_manual_compressor(void) -+{ -+ if (jffs2_bbc_get_compression_mode() != JFFS2_BBC_MANUAL_MODE) { -+ jffs2_bbc_manual_compressor = NULL; -+ } -+ return jffs2_bbc_manual_compressor; -+} -+ -+/********************************************************************* -+ * Compressor handling * -+ *********************************************************************/ -+ -+struct jffs2_bbc_compressor_type *jffs2_bbc_get_compressor_list(void) -+{ -+ return jffs2_bbc_compressors; -+} -+ -+struct jffs2_bbc_model_list_node *jffs2_bbc_get_model_list(void) -+{ -+ return jffs2_bbc_model_list; -+} -+ -+int jffs2_bbc_register_compressor(struct jffs2_bbc_compressor_type *c) -+{ -+ struct jffs2_bbc_compressor_type *l; -+ struct jffs2_bbc_model_list_node *l2; -+ int model_found = 0; -+ -+ l = jffs2_bbc_compressors; -+ /* Check for confilcts */ -+ while (l != NULL) { -+ c->name[15] = 0; -+ /*if (strcmp(c->name,l->name)==0) { -+ jffs2_bbc_print1("jffs2.bbc: compressor is already loaded."); -+ return -1; -+ } */ -+ if ((l->model_file_sign == c->model_file_sign) && (c->model_file_sign != 0)) { -+ jffs2_bbc_print1("jffs2.bbc: already used model file sign. fail."); -+ return -1; -+ } -+ l = l->next; -+ } -+ /* Search and initialize model */ -+ c->models = NULL; -+ c->mounted = 0; -+ if (c->init != NULL) { -+ if (c->init() != 0) { -+ jffs2_bbc_print2("jffs2.bbc: cannot initialize compressor %s.\n", c->name); -+ return -1; -+ } -+ } -+ if (c->model_file_sign != 0) { -+ l2 = jffs2_bbc_model_list; -+ while (1) { -+ if (l2 == NULL) -+ break; -+ if (c->model_file_sign == l2->sign) { -+ if (l2->compressor != NULL) { -+ jffs2_bbc_print2("jffs2.bbc: register for %s: BUG, model file already reserved!!!!\n", c->name); -+ } -+ else { -+ if (c->init_model(&(l2->model)) != 0) { -+ jffs2_bbc_print2("jffs2.bbc: cannot initialize compressor %s for a model", c->name); -+ } -+ else { -+ l2->compressor = c; -+ l2->next_compr_model = c->models; -+ c->models = l2; -+ c->mounted++; -+ model_found++; -+ } -+ } -+ } -+ l2 = l2->next_model; -+ } -+ /*if (model_found==0) { -+ jffs2_bbc_print2("jffs2.bbc: no macthing model file found for %s at this time (maybe later)\n",c->name); -+ } */ -+ } -+ /* Insert to the end of the compressor list */ -+ c->enabled = 1; -+ c->buffer = NULL; -+ c->buffer_size = 0; -+ c->stat_compr_orig = c->stat_compr_new = c->stat_decompr = 0; -+ c->next = NULL; -+ if (jffs2_bbc_compressors == NULL) { -+ jffs2_bbc_compressors = c; -+ } -+ else { -+ l = jffs2_bbc_compressors; -+ while (l->next != NULL) -+ l = l->next; -+ l->next = c; -+ } -+ return 0; -+} -+ -+int jffs2_bbc_unregister_compressor(struct jffs2_bbc_compressor_type *c) -+{ -+ struct jffs2_bbc_compressor_type *l; -+ struct jffs2_bbc_model_list_node *l2; -+ -+ if (c->mounted != 0) { -+ jffs2_bbc_print1("jffs2.bbc: Compressor is in use. Sorry."); -+ return -1; -+ } -+ if (jffs2_bbc_compressors == NULL) { -+ jffs2_bbc_print1("jffs2.bbc: unregister: empty list."); -+ return -1; -+ } -+ else if (jffs2_bbc_compressors == c) { -+ if (c->deinit != NULL) -+ c->deinit(); -+ jffs2_bbc_compressors = c->next; -+ } -+ else { -+ l = jffs2_bbc_compressors; -+ while (l->next != c) { -+ if (l->next == NULL) { -+ jffs2_bbc_print2("jffs2.bbc: unregister: cannot find compressor %s in the list.", c->name); -+ return -1; -+ } -+ l = l->next; -+ } -+ if (c->deinit != NULL) -+ c->deinit(); -+ l->next = c->next; -+ } -+ if (c->buffer != NULL) { -+ jffs2_bbc_free(c->buffer); -+ c->buffer = NULL; -+ c->buffer_size = 0; -+ } -+ -+ l2 = jffs2_bbc_model_list; -+ while (l2 != NULL) { -+ if (l2->compressor == c) { -+ jffs2_bbc_print1("jffs2.bbc: unregister: BUG: model found!!!"); -+ l2->compressor = NULL; -+ l2->next_compr_model = NULL; -+ } -+ l2 = l2->next_model; -+ } -+ -+ return 0; -+} -+ -+int jffs2_bbc_model_new(void *sb, int i_num, void *model) -+{ -+ struct jffs2_bbc_model_list_node *node; -+ struct jffs2_bbc_compressor_type *l; -+ char block_sign[2]; -+ -+ int sign; -+ -+ /* check for conflicts... */ -+ sign = *((int *) model); -+ block_sign[0] = *(((char *) model) + 4); -+ block_sign[1] = *(((char *) model) + 5); -+ node = jffs2_bbc_model_list; -+ while (node != NULL) { -+ if ((node->block_sign[0] == block_sign[0]) && (node->block_sign[1] == block_sign[1]) && (node->sb == sb)) { -+ //jffs2_bbc_print2("jffs2.bbc: model_new: model conflict (inode=%d)!\n",i_num); -+ return -1; -+ } -+ node = node->next_model; -+ } -+ -+ /* insertion */ -+ node = jffs2_bbc_malloc_small((long)sizeof(struct jffs2_bbc_model_list_node)); -+ node->sb = sb; -+ node->model = model; -+ node->sign = *((int *) model); -+ node->block_sign[0] = *(((char *) model) + 4); -+ node->block_sign[1] = *(((char *) model) + 5); -+ node->inode = i_num; -+ node->next_model = jffs2_bbc_model_list; -+ node->compressor = NULL; -+ node->stat_decompr = 0; -+ node->next_compr_model = NULL; -+ jffs2_bbc_model_list = node; -+ -+ /* search for matching compressor */ -+ l = jffs2_bbc_compressors; -+ while (l != NULL) { -+ if (l->model_file_sign == sign) { -+ //jffs2_bbc_print2("jffs2.bbc: compressor for model found: %s ",l->name); -+ if (l->init_model(&(node->model)) != 0) { -+ jffs2_bbc_print1("jffs2.bbc: cannot initialize compressor for a model"); -+ } -+ else { -+ l->mounted++; -+ node->compressor = l; -+ node->next_compr_model = l->models; -+ l->models = node; -+ } -+ break; -+ } -+ l = l->next; -+ } -+ return 0; -+} -+ -+static void jffs2_bbc_model_del_from_compressor(struct jffs2_bbc_model_list_node *node) -+{ -+ struct jffs2_bbc_model_list_node *l; -+ -+ if (node->model != NULL) { -+ if (node->compressor != NULL) { -+ if (node->compressor->destroy_model == NULL) { -+ jffs2_bbc_free(node->model); -+ node->model = NULL; -+ } -+ else { -+ node->compressor->destroy_model(&(node->model)); -+ if (node->model != NULL) -+ jffs2_bbc_print1("jffs2.bbc: warning: not NULL model after destroying!\n"); -+ } -+ } -+ } -+ -+ if (node->compressor == NULL) { -+ jffs2_bbc_print1("jffs2.bbc: jffs2_bbc_model_del_from_compressor: no compressor!\n"); -+ return; -+ } -+ l = node->compressor->models; -+ if (l == NULL) { -+ jffs2_bbc_print1("jffs2.bbc: jffs2_bbc_model_del_from_compressor error, models=NULL!\n"); -+ return; -+ } -+ if (l == node) { -+ node->compressor->models = node->next_compr_model; -+ node->compressor->mounted--; -+ return; -+ } -+ while (1) { -+ if (l->next_compr_model == node) { -+ l->next_compr_model = node->next_compr_model; -+ node->compressor->mounted--; -+ return; -+ } -+ l = l->next_compr_model; -+ if (l == NULL) { -+ jffs2_bbc_print1("jffs2.bbc: jffs2_bbc_model_del_from_compressor: not found\n"); -+ return; -+ } -+ } -+} -+ -+void jffs2_bbc_model_del(void *sb) -+{ -+ struct jffs2_bbc_model_list_node *l, *l2; -+ -+ l = jffs2_bbc_model_list; -+ if (l == NULL) -+ return; -+ if (l->sb == sb) { -+ jffs2_bbc_model_list = l->next_model; -+ jffs2_bbc_model_del_from_compressor(l); -+ jffs2_bbc_free_small(l); -+ jffs2_bbc_model_del(sb); -+ return; -+ } -+ while (1) { -+ if (l->next_model == NULL) { -+ break; -+ } -+ if (l->next_model->sb == sb) { -+ l2 = l->next_model; -+ l->next_model = l->next_model->next_model; -+ jffs2_bbc_model_del_from_compressor(l2); -+ jffs2_bbc_free_small(l2); -+ jffs2_bbc_model_del(sb); -+ return; -+ } -+ l = l->next_model; -+ } -+ last_sb = NULL; -+} -+ -+void jffs2_bbc_model_set_act_sb(void *sb) -+{ -+ last_sb = sb; -+} -+ -+void *jffs2_bbc_model_get_act_sb(void) -+{ -+ return last_sb; -+} -+ -+void *jffs2_bbc_model_get_newest(struct jffs2_bbc_compressor_type *compressor) -+{ -+ struct jffs2_bbc_model_list_node *m, *best_m; -+ int max_sign, sign; -+ -+ if (compressor == NULL) { -+ jffs2_bbc_print1("jffs2.bbc: jffs2_bbc_model_get: NULL!!\n"); -+ return NULL; -+ } -+ -+ best_m = NULL; -+ max_sign = -1; -+ m = compressor->models; -+ while (m != NULL) { -+ if (m->sb == last_sb) { -+ sign = (int) (m->block_sign[0]) * 256 + (int) (m->block_sign[1]); -+ if (sign > max_sign) { -+ max_sign = sign; -+ best_m = m; -+ } -+ } -+ m = m->next_compr_model; -+ } -+ if (best_m != NULL) -+ return best_m->model; -+ else -+ return NULL; -+} -+ -+/********************************************************************* -+ * Statistics * -+ *********************************************************************/ -+ -+static char *jffs2_bbc_stat_buff = NULL; -+ -+char *jffs2_bbc_get_model_stats(void) -+{ -+ char *b; -+ struct jffs2_bbc_model_list_node *m; -+ struct jffs2_bbc_compressor_type *c; -+ -+ if (jffs2_bbc_stat_buff == NULL) -+ jffs2_bbc_stat_buff = jffs2_bbc_malloc(8000); -+ -+ b = jffs2_bbc_stat_buff; -+ -+ b += sprintf(b, "Loaded compressors:"); -+ c = jffs2_bbc_compressors; -+ while (c != NULL) { -+ b += sprintf(b, "\n %s (%d) ", c->name, c->enabled); -+ if (c->model_file_sign != 0) { -+ b += sprintf(b, "m_sign=%d ", c->model_file_sign); -+ b += sprintf(b, "models="); -+ m = c->models; -+ while (m != NULL) { -+ b += sprintf(b, "(inode=%d)", m->inode); -+ m = m->next_compr_model; -+ } -+ } -+ else { -+ b += sprintf(b, "b_sign=(%d,%d) nomodel", (int) (c->block_sign[0]), (int) (c->block_sign[1])); -+ } -+ if (c->proc_info != NULL) { -+ b += sprintf(b, "\n %s", c->proc_info()); -+ } -+ c = c->next; -+ } -+ -+ m = jffs2_bbc_model_list; -+ -+ if (m == NULL) { -+ b += sprintf(b, "\nPresent models: NONE\n"); -+ } -+ else { -+ b += sprintf(b, "\nPresent models:\n"); -+ while (m != NULL) { -+ b += sprintf(b, " b_sign=(%d,%d),inode=%d,decompr=%d", (int) (m->block_sign[0]), (int) (m->block_sign[1]), m->inode, m->stat_decompr); -+ if (m->compressor == NULL) -+ b += sprintf(b, ",compressor=NULL\n"); -+ else -+ b += sprintf(b, ",compressor=%s\n", m->compressor->name); -+ m = m->next_model; -+ } -+ } -+ -+ return jffs2_bbc_stat_buff; -+} -+ -+/********************************************************************* -+ * Memory handling, debug * -+ *********************************************************************/ -+ -+static int jffs2_bbc_mem_counter = 0; -+ -+#ifdef __KERNEL__ -+ -+void *jffs2_bbc_malloc(long size) -+{ -+ void *addr = vmalloc(size); -+ if (addr != NULL) -+ jffs2_bbc_mem_counter++; -+ else { -+ jffs2_bbc_print2("DEBUG: not enough memory (%ld)\n", size); -+ } -+ return addr; -+} -+ -+void jffs2_bbc_free(void *addr) -+{ -+ jffs2_bbc_mem_counter--; -+ vfree(addr); -+} -+ -+void *jffs2_bbc_malloc_small(long size) -+{ -+ void *addr; -+ addr = kmalloc(size, 0); -+ if (addr != NULL) -+ jffs2_bbc_mem_counter++; -+ return addr; -+} -+ -+void jffs2_bbc_free_small(void *addr) -+{ -+ jffs2_bbc_mem_counter--; -+ kfree(addr); -+} -+ -+#else -+ -+void *jffs2_bbc_malloc(long size) -+{ -+ void *addr = malloc(size); -+ if (addr != NULL) -+ jffs2_bbc_mem_counter++; -+ return addr; -+} -+ -+void jffs2_bbc_free(void *addr) -+{ -+ jffs2_bbc_mem_counter--; -+ free(addr); -+} -+ -+void *jffs2_bbc_malloc_small(long size) -+{ -+ return jffs2_bbc_malloc(size); -+} -+ -+void jffs2_bbc_free_small(void *addr) -+{ -+ jffs2_bbc_free(addr); -+} -+ -+#endif -+ -+int jffs2_bbc_test_memory_counter(int verbose) -+{ -+ if (verbose > 0) { -+ jffs2_bbc_print2("jffs2.bbc: mem_counter=%d!\n", jffs2_bbc_mem_counter); -+ } -+ return jffs2_bbc_mem_counter; -+} -+ -+int jffs2_bbc_get_memory_counter(void) -+{ -+ return jffs2_bbc_mem_counter; -+} -+ -+static char mem_stat[200]; -+ -+char *jffs2_bbc_get_mem_stats(void) -+{ -+ sprintf(mem_stat, "Memcounter=%d\n", jffs2_bbc_mem_counter); -+ return mem_stat; -+} -+ -+void jffs2_bbc_print_flush(void) -+{ -+#ifdef __KERNEL__ -+ return; -+#else -+ fflush(stdout); -+ fflush(stderr); -+#endif -+} -+ -+/********************************************************************* -+ * FRAMEWORK - ZLIB REPLACEMENT * -+ *********************************************************************/ -+ -+#ifndef JFFS2_BBC_STANDALONE -+ -+/* Temorary buffers */ -+static char stat_str[JFFS2_BBC_STAT_BUFF_SIZE]; -+static int tmp_buffer_size = 0; -+static char *tmp_buffer = NULL; -+ -+/* Statistic - used by /proc/jffs2_bbc and mkfs.jffs2 */ -+char *jffs2_bbc_get_compr_stats(void) -+{ -+ struct jffs2_bbc_compressor_type *l; -+ char *s = stat_str; -+ -+ s += sprintf(s, "Compression statistics:\n"); -+ l = jffs2_bbc_original_compressor; -+ //s += sprintf(s, " zlib: compr=%d/%d decompr=%d\n", stat_zlib_compr_new, stat_zlib_compr_orig, stat_zlib_decompr); -+ s += sprintf(s, " %s: compr=%d/%d decompr=%d\n", l->name, l->stat_compr_new, l->stat_compr_orig, l->stat_decompr); -+ l = jffs2_bbc_get_compressor_list(); -+ while (l != NULL) { -+ s += sprintf(s, " %s: compr=%d/%d decompr=%d\n", l->name, l->stat_compr_new, l->stat_compr_orig, l->stat_decompr); -+ l = l->next; -+ } -+ return stat_str; -+} -+ -+static void jffs2_bbc_buffer_fill(unsigned char *buff, int size) -+{ -+ for (; size > 0; size--, buff++) -+ *buff = 255; -+} -+ -+ -+static int jffs2_bbc_update_compr_buf(unsigned long size) -+{ -+ struct jffs2_bbc_compressor_type *l; -+ -+ if (size < 5000) -+ size = 5000; -+ if (tmp_buffer == NULL) { -+ tmp_buffer = jffs2_bbc_malloc(size); -+ jffs2_bbc_buffer_fill(tmp_buffer, size); -+ tmp_buffer_size = size; -+ } -+ else if (tmp_buffer_size < size) { -+ jffs2_bbc_free(tmp_buffer); -+ tmp_buffer = jffs2_bbc_malloc(size); -+ jffs2_bbc_buffer_fill(tmp_buffer, size); -+ tmp_buffer_size = size; -+ } -+ l = jffs2_bbc_get_compressor_list(); -+ while (l != NULL) { -+ if (l->buffer == NULL) { -+ l->buffer_size = size; -+ l->buffer = jffs2_bbc_malloc(size); -+ jffs2_bbc_buffer_fill(l->buffer, size); -+ } -+ else if (l->buffer_size < size) { -+ jffs2_bbc_free(l->buffer); -+ l->buffer_size = size; -+ l->buffer = jffs2_bbc_malloc(size); -+ jffs2_bbc_buffer_fill(l->buffer, size); -+ } -+ l = l->next; -+ } -+ return 0; -+} -+ -+#ifdef DEBUG_COMPRESSORS -+ -+static unsigned char *debug_tmp_buff = NULL; -+static long debug_orig_srclen = -1; -+static long debug_orig_dstlen = -1; -+static int debug_mem_counter = -1; -+ -+ -+void debug_before_compress(struct jffs2_bbc_compressor_type *c, void *model, unsigned char *input, unsigned char *output, long *sourcelen, long *dstlen) -+{ -+ -+ debug_orig_srclen = *sourcelen; // for buffer overflow test -+ debug_orig_dstlen = *dstlen; // for buffer overflow test -+ output[debug_orig_dstlen + 1] = 255; -+ -+ debug_mem_counter = jffs2_bbc_get_memory_counter(); // for memory guard -+} -+ -+void debug_after_compress(struct jffs2_bbc_compressor_type *c, int back, void *model, unsigned char *input, unsigned char *output, long *sourcelen, long *dstlen) -+{ -+ long dst_len = *dstlen; -+ long src_len = *sourcelen; -+ int i; -+ -+ // Memory guard -+ if (debug_mem_counter != jffs2_bbc_get_memory_counter()) { -+ jffs2_bbc_print4("!!!!!!!! %s error: possible COMPRESSOR MEMORY LEAK: %d->%d\n", c->name, debug_mem_counter, jffs2_bbc_get_memory_counter()); -+ debug_mem_counter = jffs2_bbc_get_memory_counter(); -+ } -+ -+ // Buffer overflow test -+ if (output[debug_orig_dstlen + 1] != 255) { -+ jffs2_bbc_print7("!!!!!!!! %s error: BUFFER OVERFLOW !!!!!!!!!!!! b[%d]=%d (srclen=%d dstlen=%d, back=%d)\n", c->name, (int) (debug_orig_dstlen + 1), (int) (output[debug_orig_dstlen + 1]), (int) (debug_orig_srclen), (int) (*dstlen), back); -+ } -+ -+ // Decompression check -+ if (back == 0) { -+ if (debug_tmp_buff == NULL) -+ debug_tmp_buff = jffs2_bbc_malloc(17000); -+ for (i = 0; i < src_len; i++) debug_tmp_buff[i] = 0xf6; -+ c->decompress(model, output, debug_tmp_buff, dst_len, src_len); -+ // Memory guard for decompressor -+ if (debug_mem_counter != jffs2_bbc_get_memory_counter()) { -+ jffs2_bbc_print4("!!!!!!!! %s error: possible DECOMPRESSOR MEMORY LEAK: %d->%d\n", c->name, debug_mem_counter, jffs2_bbc_get_memory_counter()); -+ debug_mem_counter = jffs2_bbc_get_memory_counter(); -+ } -+ -+ for (i = 0; i < src_len; i++) -+ if (input[i] != debug_tmp_buff[i]) { -+ jffs2_bbc_print7("!!!!!!!! %s error: BLOCK DECOMPRESSED BADLY (first bad: %d in %d: %d!=%d (compressed size=%d)) !!!!!!!!!!!!\n", c->name, i, src_len, (int)input[i], (int)debug_tmp_buff[i], dst_len); -+ break; -+ } -+ return; -+ } -+ -+ // Return value test -+ //jffs2_bbc_print3("!!!!!!!! %s error: %d !!!!!!!!!!!!\n", c->name, back); -+} -+ -+#endif -+ -+int jffs2_zlib_compress(unsigned char *data_in, unsigned char *cpage_out, uint32_t * sourcelen, uint32_t * dstlen) -+{ -+ struct jffs2_bbc_compressor_type *c; -+ int back, back_zlib, mode, min, i, i2; -+ long tmp = 0, tmp_read_time = 1000, tmp_write_time = 1000, orig_src, orig_dest, src, dest; -+ struct jffs2_bbc_model_list_node *m; -+ void *sb; -+ unsigned char *tmp_p = NULL; -+ -+ sb = jffs2_bbc_model_get_act_sb(); -+ -+ orig_src = *sourcelen; -+ orig_dest = *dstlen; -+ -+ mode = jffs2_bbc_get_compression_mode(); -+ -+ if (mode == JFFS2_BBC_DUMMY_MODE) { -+ i=0; i2=0; -+ if (*dstlen>2) { -+ cpage_out[i++]=JFFS2_BBC_DUMMY_BLOCKSIGN_0; -+ cpage_out[i++]=JFFS2_BBC_DUMMY_BLOCKSIGN_1; -+ i2=i; -+ } -+ for (;((i < *dstlen) && (i < (*sourcelen)+i2));i++) { -+ cpage_out[i] = data_in[i-i2]; -+ } -+ *sourcelen=i-i2; -+ *dstlen=i; -+ return 0; -+ } -+ -+ if (mode == JFFS2_BBC_ZLIB_MODE) { -+ /*if (!jffs2_bbc_original_compressor->enabled) { -+ jffs2_bbc_print2("jffs2.bbc: WARNING: ZLIB mode but %s disabled! Enabling for this procedure...\n",jffs2_bbc_original_compressor->name); -+ }*/ -+ back = jffs2_bbc_original_compressor->compress(NULL, data_in, cpage_out, sourcelen, dstlen); -+ jffs2_bbc_original_compressor->stat_compr_orig += *sourcelen; -+ jffs2_bbc_original_compressor->stat_compr_new += *dstlen; -+ return back; -+ } -+ -+ jffs2_bbc_update_compr_buf(orig_dest); -+ -+ if (mode == JFFS2_BBC_SIZE_MODE) { -+ // Testing all compressors -+ if (!jffs2_bbc_original_compressor->enabled) { -+ min = -1; -+ } -+ else { -+ back_zlib = jffs2_bbc_original_compressor->compress(NULL, data_in, cpage_out, sourcelen, dstlen); -+ min = *dstlen; -+ } -+ c = jffs2_bbc_get_compressor_list(); -+ while (c != NULL) { -+ c->buffer_cnt = -1; -+ if (c->enabled == 0) { -+ c = c->next; -+ continue; -+ } -+ if (c->model_file_sign == 0) { -+ src = orig_src; -+ dest = orig_dest; -+#ifdef DEBUG_COMPRESSORS -+ debug_before_compress(c, NULL, data_in, c->buffer, &src, &dest); -+#endif -+ back = c->compress(NULL, data_in, c->buffer, &src, &dest); -+#ifdef DEBUG_COMPRESSORS -+ debug_after_compress(c, back, NULL, data_in, c->buffer, &src, &dest); -+#endif -+ if (back == 0) { -+ c->buffer_cnt = dest; -+ if ((min < 0) || (min > dest)) -+ min = dest; -+ } -+ } -+ else { -+ m = c->models; -+ while (m != NULL) { -+ src = orig_src; -+ dest = orig_dest; -+ if (m->sb == sb) { -+ if (c->buffer_cnt == -1) { -+#ifdef DEBUG_COMPRESSORS -+ debug_before_compress(c, m->model, data_in, c->buffer, (long *) (&src), (long *) (&dest)); -+#endif -+ back = c->compress(m->model, data_in, c->buffer, (long *) (&src), (long *) (&dest)); -+#ifdef DEBUG_COMPRESSORS -+ debug_after_compress(c, back, m->model, data_in, c->buffer, (long *) (&src), (long *) (&dest)); -+#endif -+ if (back == 0) { -+ c->buffer_cnt = dest; -+ if ((min < 0) || (min > dest)) -+ min = dest; -+ } -+ } -+ else { -+#ifdef DEBUG_COMPRESSORS -+ debug_before_compress(c, m->model, data_in, tmp_buffer, &src, &dest); -+#endif -+ back = c->compress(m->model, data_in, tmp_buffer, &src, &dest); -+#ifdef DEBUG_COMPRESSORS -+ debug_after_compress(c, back, m->model, data_in, tmp_buffer, &src, &dest); -+#endif -+ if (back == 0) { -+ if (c->buffer_cnt > dest) { -+ c->buffer_cnt = dest; -+ tmp_p = c->buffer; -+ c->buffer = tmp_buffer; -+ tmp_buffer = tmp_p; -+ if ((min < 0) || (min > dest)) -+ min = dest; -+ } -+ } -+ } -+ } -+ m = m->next_compr_model; -+ } -+ } -+ c = c->next; -+ } -+ //Finding the best and copy its result -+ -+#ifdef DEBUG_SHOW_BLOCK_SIZES -+ jffs2_bbc_print1("\n"); -+ if (jffs2_bbc_original_compressor->enabled) { -+ if (min == *dstlen) { -+ jffs2_bbc_print3("%s:%d* ", jffs2_bbc_original_compressor->name, (int) (*dstlen)); -+ } -+ else { -+ jffs2_bbc_print3("%s:%d ", jffs2_bbc_original_compressor->name, (int) (*dstlen)); -+ } -+ } -+ c = jffs2_bbc_get_compressor_list(); -+ while (c != NULL) { -+ if (c->enabled == 0) { -+ c = c->next; -+ continue; -+ } -+ if (c->buffer_cnt == min) -+ jffs2_bbc_print3("%s:%d* ", c->name, c->buffer_cnt); -+ else -+ jffs2_bbc_print3("%s:%d ", c->name, c->buffer_cnt); -+ c = c->next; -+ } -+#endif -+ -+ if (min == -1) { -+ return -1; // none of compressors work (maybe too short output buffer) -+ } -+ -+ if (jffs2_bbc_original_compressor->enabled) { -+ if (min == *dstlen) { -+ jffs2_bbc_original_compressor->stat_compr_orig += *sourcelen; -+ jffs2_bbc_original_compressor->stat_compr_new += *dstlen; -+ return back_zlib; -+ } -+ } -+ -+ c = jffs2_bbc_get_compressor_list(); -+ while (c != NULL) { -+ if (c->enabled == 0) { -+ c = c->next; -+ continue; -+ } -+ if (c->buffer_cnt == min) { -+ *dstlen = c->buffer_cnt; -+ *sourcelen = orig_src; -+ for (i = 0; i < *dstlen; i++) { -+ cpage_out[i] = c->buffer[i]; -+ } -+ c->stat_compr_orig += *sourcelen; -+ c->stat_compr_new += *dstlen; -+ return 0; -+ } -+ c = c->next; -+ } -+ jffs2_bbc_print1("jffs2.bbc: compr (full): BUG!!!\n"); -+ return 0; -+ } -+ -+ if ((mode == JFFS2_BBC_FASTR_MODE)||(mode == JFFS2_BBC_FASTW_MODE)||(mode == JFFS2_BBC_FASTS_MODE)) { -+ // Estimating all compressors -+ if (jffs2_bbc_original_compressor->enabled) { -+ back = jffs2_bbc_original_compressor->estimate(NULL, data_in, *sourcelen, &tmp, &tmp_read_time, &tmp_write_time); -+ } -+ else { -+ tmp = -1; -+ tmp_read_time = -1; -+ tmp_write_time = -1; -+ } -+ if (mode == JFFS2_BBC_FASTR_MODE) tmp = tmp_read_time; -+ if (mode == JFFS2_BBC_FASTW_MODE) tmp = tmp_write_time; -+ min = tmp; -+ c = jffs2_bbc_get_compressor_list(); -+ while (c != NULL) { -+ src = orig_src; -+ dest = orig_dest; -+ c->buffer_cnt = -1; -+ if (c->enabled == 0) { -+ c = c->next; -+ continue; -+ } -+ if ((c->model_file_sign == 0) || (jffs2_bbc_model_get_newest(c) != NULL)) { -+ back = c->estimate(jffs2_bbc_model_get_newest(c), data_in, src, &dest, &tmp_read_time, &tmp_write_time); -+ if (mode == JFFS2_BBC_FASTR_MODE) dest = tmp_read_time; -+ if (mode == JFFS2_BBC_FASTW_MODE) dest = tmp_write_time; -+ if (back == 0) { -+ c->buffer_cnt = dest; -+ if ((min < 0) || (min > dest)) -+ min = dest; -+ } -+ else { -+ c->buffer_cnt = -1; -+ } -+ } -+ c = c->next; -+ } -+ // Finding the best and compress with it -+ if (min == -1) { -+ return -1; -+ } -+ if (jffs2_bbc_original_compressor->enabled) { -+ if (min == tmp) { -+ back = jffs2_bbc_original_compressor->compress(NULL, data_in, cpage_out, sourcelen, dstlen); -+ jffs2_bbc_original_compressor->stat_compr_orig += *sourcelen; -+ jffs2_bbc_original_compressor->stat_compr_new += *dstlen; -+ return back; -+ } -+ } -+ c = jffs2_bbc_get_compressor_list(); -+ while (c != NULL) { -+ if (c->enabled == 0) { -+ c = c->next; -+ continue; -+ } -+ if (c->buffer_cnt == min) { -+ back = c->compress(jffs2_bbc_model_get_newest(c), data_in, cpage_out, (unsigned long*)sourcelen, (unsigned long*)dstlen); -+ if ((back == 0) && (*dstlen < orig_dest) && (*dstlen > 4)) { -+ c->stat_compr_orig += *sourcelen; -+ c->stat_compr_new += *dstlen; -+ } -+ else { // fallback will always be available -+ *sourcelen = orig_src; -+ *dstlen = orig_dest; -+ back = jffs2_bbc_original_compressor->compress(NULL, data_in, cpage_out, sourcelen, dstlen); -+ jffs2_bbc_original_compressor->stat_compr_orig += *sourcelen; -+ jffs2_bbc_original_compressor->stat_compr_new += *dstlen; -+ return back; -+ } -+ return 0; -+ } -+ c = c->next; -+ } -+ jffs2_bbc_print1("jffs2.bbc: compress (fastX mode): BUG!!!\n"); -+ return 0; -+ } -+ -+ if (mode == JFFS2_BBC_MANUAL_MODE) { -+ c = jffs2_bbc_get_manual_compressor(); -+ if (c != NULL) { -+ if (c->model_file_sign == 0) { -+ src = orig_src; -+ dest = orig_dest; -+ back = c->compress(NULL, data_in, cpage_out, &src, &dest); -+ if (back == 0) { -+ *dstlen = dest; -+ *sourcelen = src; -+ c->stat_compr_orig += *sourcelen; -+ c->stat_compr_new += *dstlen; -+ return 0; -+ } -+ } -+ else { -+ c->buffer_cnt = -1; -+ m = c->models; -+ min = -1; -+ while (m != NULL) { -+ src = orig_src; -+ dest = orig_dest; -+ if (m->sb == sb) { -+ if (min == -1) { -+ back = c->compress(m->model, data_in, cpage_out, (unsigned long*)sourcelen, (unsigned long*)dstlen); -+ if ((back == 0) && (*dstlen < orig_dest) && (*dstlen > 4)) { -+ min = dest; -+ tmp_p = cpage_out; -+ } -+ } -+ else { -+ back = c->compress(m->model, data_in, tmp_buffer, &src, &dest); -+ if ((back == 0) && (dest < orig_dest) && (dest > 4)) { -+ if (c->buffer_cnt > dest) { -+ if (min > dest) { -+ min = dest; -+ tmp_p = tmp_buffer; -+ } -+ } -+ } -+ } -+ } -+ m = m->next_compr_model; -+ } -+ if (min != -1) { -+ if (tmp_p != cpage_out) { -+ for (i = 0; i < min; i++) -+ cpage_out[i] = tmp_p[i]; -+ *sourcelen = orig_src; -+ *dstlen = min; -+ } -+ c->stat_compr_orig += *sourcelen; -+ c->stat_compr_new += *dstlen; -+ return 0; -+ } -+ } -+ } -+ /*else { -+ jffs2_bbc_print1("iPack: manual mode without selected compressor!\n"); -+ } */ -+ -+ /*if (!jffs2_bbc_original_compressor->enabled) { -+ jffs2_bbc_print2("jffs2.bbc: WARNING: %s must be enabled! Enabling for this procedure...\n",jffs2_bbc_original_compressor->name); -+ }*/ -+ back = jffs2_bbc_original_compressor->compress(NULL, data_in, cpage_out, sourcelen, dstlen); -+ jffs2_bbc_original_compressor->stat_compr_orig += *sourcelen; -+ jffs2_bbc_original_compressor->stat_compr_new += *dstlen; -+ return back; -+ -+ -+ } -+ -+ jffs2_bbc_print1("jffs2.bbc: compress: unimlemented compress mode!!!\n"); -+ return 0; -+} -+ -+void jffs2_zlib_decompress(unsigned char *data_in, unsigned char *cpage_out, uint32_t srclen, uint32_t destlen) -+{ -+ struct jffs2_bbc_model_list_node *m; -+ struct jffs2_bbc_compressor_type *c; -+ char d[2]; -+ void *sb; -+ int i; -+ -+ /* If the input too small... */ -+ if (destlen<=2) { -+ cpage_out[0]=data_in[0]; -+ if (destlen==2) cpage_out[1]=data_in[1]; -+ return; -+ } -+ -+ sb = jffs2_bbc_model_get_act_sb(); -+ d[0] = *(data_in); -+ d[1] = *(data_in + 1); -+ -+ d[0] &= 0x7f; // Variants support... -+ -+ /* Search for model based decompressors... */ -+ m = jffs2_bbc_get_model_list(); -+ while (m != NULL) { -+ if ((d[0] == m->block_sign[0]) && (d[1] == m->block_sign[1]) && (sb == m->sb)) { -+ if (m->compressor == NULL) { -+ jffs2_bbc_print3("jffs2.bbc: decompressor for block_sign (%d,%d) not loaded!\n", (int) (d[0]), (int) (d[1])); -+ } -+ else { -+ m->compressor->decompress(m->model, data_in, cpage_out, srclen, destlen); -+ m->compressor->stat_decompr++; -+ m->stat_decompr++; -+ } -+ return; -+ } -+ m = m->next_model; -+ } -+ /* Is it ZLIB? */ -+ if ((((int) d[0]) == (int)(jffs2_bbc_original_compressor->block_sign[0])) && (((int) d[1]) == (int)(jffs2_bbc_original_compressor->block_sign[1]))) { -+ jffs2_bbc_original_compressor->decompress(NULL, data_in, cpage_out, srclen, destlen); -+ jffs2_bbc_original_compressor->stat_decompr++; -+ return; -+ } -+ /* Search for non model based decompressors... */ -+ c = jffs2_bbc_get_compressor_list(); -+ while (c != NULL) { -+ if (c->model_file_sign == 0) { -+ if (((int) (d[0]) == (int) (c->block_sign[0])) && ((int) (d[1]) == (int) (c->block_sign[1]))) { -+ c->decompress(NULL, data_in, cpage_out, srclen, destlen); -+ c->stat_decompr++; -+ return; -+ } -+ } -+ c = c->next; -+ } -+ /* Is it DUMMY? */ -+ if ((((int) d[0]) == JFFS2_BBC_DUMMY_BLOCKSIGN_0) && (((int) d[1]) == JFFS2_BBC_DUMMY_BLOCKSIGN_1)) { -+ for (i=0;i<destlen;i++) { -+ cpage_out[i]=data_in[i+2]; -+ } -+ return; -+ } -+ /* No matching decompressor found... */ -+ jffs2_bbc_print4("jffs2.bbc: cannot find model for decompress: bsign=(%d,%d),sb=%d. Using zlib.\n", (int) d[0], (int) d[1], (int) sb); -+ jffs2_bbc_original_compressor->decompress(NULL, data_in, cpage_out, srclen, destlen); -+ jffs2_bbc_original_compressor->stat_decompr++; -+} -+ -+#endif -diff -Nur linux-mips-cvs/fs/jffs2/jffs2_bbc_framework.h linux-mips/fs/jffs2/jffs2_bbc_framework.h ---- linux-mips-cvs/fs/jffs2/jffs2_bbc_framework.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-mips/fs/jffs2/jffs2_bbc_framework.h 2005-02-07 05:08:34.000000000 +0100 -@@ -0,0 +1,202 @@ -+/* -+ * JFFS2-BBC: Compression Framework - headers -+ * -+ * $Id: 301-jffs-compression,v 1.1 2005/03/26 10:33:31 wbx Exp $ -+ * -+ * Copyright (C) 2004, Ferenc Havasi -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version 2 -+ * of the License, or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -+ * -+ */ -+ -+#ifndef __JFFS2_BBC_FRAMEWORK_H__ -+ -+#define __JFFS2_BBC_FRAMEWORK_H__ -+ -+#define JFFS2_BBC_VERSION "0.54.3" -+ -+#define JFFS2_BBC_CONFIG_FILE "bbc.conf" -+ -+/********************************************************************* -+ * Compression mode handling * -+ *********************************************************************/ -+ -+#define JFFS2_BBC_ZLIB_MODE 1 -+#define JFFS2_BBC_SIZE_MODE 2 -+#define JFFS2_BBC_FASTR_MODE 3 -+#define JFFS2_BBC_FASTW_MODE 4 -+#define JFFS2_BBC_FASTS_MODE 5 -+#define JFFS2_BBC_MANUAL_MODE 6 -+#define JFFS2_BBC_DUMMY_MODE 7 -+ -+int jffs2_bbc_get_compression_mode(void); -+void jffs2_bbc_set_compression_mode(int mode); -+ -+/********************************************************************* -+ * Read/write speed unit * -+ * everything is relative to the speed of zlib * -+ * bigger number means slower speed! * -+ *********************************************************************/ -+ -+#define JFFS2_BBC_ZLIB_READ_TIME 10000 -+#define JFFS2_BBC_ZLIB_WRITE_TIME 10000 -+ -+/********************************************************************* -+ * Compressor handling * -+ *********************************************************************/ -+ -+struct jffs2_bbc_compressor_type -+{ -+ char name[16]; -+ int model_file_sign; /* 0 for no model file needed */ -+ char block_sign[4]; /* only nomodel compressors, and only the first 2 _bytes are used! */ -+ int (*init)(void); -+ int (*init_model)(void **model); -+ void (*destroy_model)(void **model); -+ void (*deinit)(void); -+ /* Compress block -+ * *dstlen bytes are allocated. -+ * if it is not enough write *sourcelen over to the processed amount of data -+ * returns non zero if fails -+ */ -+ int (*compress)(void *model, unsigned char *input, unsigned char *output, unsigned long *sourcelen, unsigned long *dstlen); -+ int (*estimate)(void *model, unsigned char *input, unsigned long sourcelen, -+ unsigned long *dstlen, unsigned long *readtime, unsigned long *writetime); -+ /* Decompress block -+ * returns non zero if fails -+ */ -+ int (*decompress)(void *model, unsigned char *input, unsigned char *output, unsigned long sourcelen, unsigned long dstlen); -+ char *(*proc_info)(void); -+ int (*proc_command)(char *command); -+ int enabled; /* filled by BBC */ -+ int mounted; /* filled by BBC */ -+ void *models; /* filled by BBC */ -+ char *buffer; /* filled by BBC */ -+ int buffer_size; /* filled by BBC */ -+ int buffer_cnt; /* filled by BBC */ -+ int buffer_tmp; /* filled by BBC */ -+ int stat_compr_orig; /* filled by BBC */ -+ int stat_compr_new; /* filled by BBC */ -+ int stat_decompr; /* filled by BBC */ -+ struct jffs2_bbc_compressor_type *next; /* filled by BBC */ -+}; -+ -+/* It sets the compression mode to JFFS2_BBC_MANUAL_MODE */ -+ -+void jffs2_bbc_set_manual_compressor(struct jffs2_bbc_compressor_type *c); /* NULL = ZLIB */ -+int jffs2_bbc_set_manual_compressor_by_name(char *name); -+int jffs2_bbc_disable_compressor_by_name(char *name); -+int jffs2_bbc_enable_compressor_by_name(char *name); -+void jffs2_bbc_compressor_command_by_name(char *name_and_command); -+ -+/* If the compression mode is JFFS2_BCC_MANUAL_MODE the manually setted -+ compressor can be get using it. Otherwise it returns with NULL. */ -+ -+struct jffs2_bbc_compressor_type *jffs2_bbc_get_manual_compressor(void); -+ -+struct jffs2_bbc_model_list_node -+{ -+ void *sb; /* FS idendifier (JFFS2_SB_INFO(sb) at this moment) */ -+ void *model; /* model data */ -+ int sign; /* sign of the model (first 4 bytes) */ -+ char block_sign[4]; /* block sign - only the first 2 bytes are used! */ -+ int inode; /* inode number of the model file */ -+ int stat_decompr; -+ struct jffs2_bbc_compressor_type *compressor; -+ struct jffs2_bbc_model_list_node *next_model; -+ struct jffs2_bbc_model_list_node *next_compr_model; -+}; -+ -+struct jffs2_bbc_compressor_type *jffs2_bbc_get_compressor_list(void); -+struct jffs2_bbc_model_list_node *jffs2_bbc_get_model_list(void); -+ -+int jffs2_bbc_register_compressor(struct jffs2_bbc_compressor_type *c); -+int jffs2_bbc_unregister_compressor(struct jffs2_bbc_compressor_type *c); -+ -+int jffs2_bbc_model_new(void *sb, int i_num, void *model); -+void jffs2_bbc_model_del(void *sb); -+void jffs2_bbc_model_set_act_sb(void *sb); -+void *jffs2_bbc_model_get_act_sb(void); -+void *jffs2_bbc_model_get_newest(struct jffs2_bbc_compressor_type *compressor); -+ -+/********************************************************************* -+ * Compressor init function * -+ *********************************************************************/ -+ -+void jffs2_bbc_compressor_init(void); -+void jffs2_bbc_compressor_deinit(void); -+ -+/********************************************************************* -+ * Statistics * -+ *********************************************************************/ -+ -+char *jffs2_bbc_get_compr_stats(void); -+char *jffs2_bbc_get_model_stats(void); -+ -+/********************************************************************* -+ * Other * -+ *********************************************************************/ -+ -+ -+void jffs2_bbc_print_flush(void); -+ -+#ifdef __KERNEL__ -+#include <linux/kernel.h> -+#define jffs2_bbc_print1(a) printk(a) -+#define jffs2_bbc_print2(a,b) printk(a,b) -+#define jffs2_bbc_print3(a,b,c) printk(a,b,c) -+#define jffs2_bbc_print4(a,b,c,d) printk(a,b,c,d) -+#define jffs2_bbc_print5(a,b,c,d,e) printk(a,b,c,d,e) -+#define jffs2_bbc_print6(a,b,c,d,e,f) printk(a,b,c,d,e,f) -+#define jffs2_bbc_print7(a,b,c,d,e,f,g) printk(a,b,c,d,e,f,g) -+#define jffs2_bbc_print8(a,b,c,d,e,f,g,h) printk(a,b,c,d,e,f,g,h) -+#define jffs2_bbc_print9(a,b,c,d,e,f,g,h,i) printk(a,b,c,d,e,f,g,h,i) -+#else -+#include <stdio.h> -+#define jffs2_bbc_print1(a) fprintf(stderr,a) -+#define jffs2_bbc_print2(a,b) fprintf(stderr,a,b) -+#define jffs2_bbc_print3(a,b,c) fprintf(stderr,a,b,c) -+#define jffs2_bbc_print4(a,b,c,d) fprintf(stderr,a,b,c,d) -+#define jffs2_bbc_print5(a,b,c,d,e) fprintf(stderr,a,b,c,d,e) -+#define jffs2_bbc_print6(a,b,c,d,e,f) fprintf(stderr,a,b,c,d,e,f) -+#define jffs2_bbc_print7(a,b,c,d,e,f,g) fprintf(stderr,a,b,c,d,e,f,g) -+#define jffs2_bbc_print8(a,b,c,d,e,f,g,h) fprintf(stderr,a,b,c,d,e,f,g,h) -+#define jffs2_bbc_print9(a,b,c,d,e,f,g,h,i) fprintf(stderr,a,b,c,d,e,f,g,h,i) -+#endif -+ -+/* Handle endianness */ -+#ifndef __KERNEL__ -+ -+#define ENDIAN_HOST_AND_TARGET_SAME 0 -+#define ENDIAN_HOST_AND_TARGET_DIFFERENT 1 -+ -+extern int jffs2_bbc_glb_endian_X; -+ -+#endif -+ -+/* Allocating more than one page (tip. 4096 byte) */ -+void *jffs2_bbc_malloc(long size); -+void jffs2_bbc_free(void *addr); -+ -+/* Allocating less than one page (tip. 4096 byte) */ -+void *jffs2_bbc_malloc_small(long size); -+void jffs2_bbc_free_small(void *addr); -+ -+/* Memory guarding */ -+int jffs2_bbc_test_memory_counter(int verbose); -+char *jffs2_bbc_get_mem_stats(void); -+int jffs2_bbc_get_memory_counter(void); -+ -+#endif -diff -Nur linux-mips-cvs/fs/jffs2/jffs2_bbc_fs.c linux-mips/fs/jffs2/jffs2_bbc_fs.c ---- linux-mips-cvs/fs/jffs2/jffs2_bbc_fs.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-mips/fs/jffs2/jffs2_bbc_fs.c 2005-02-07 05:08:34.000000000 +0100 -@@ -0,0 +1,331 @@ -+/* -+ * JFFS2-BBC: File System Extension for Linux Kernel -+ * -+ * $Id: 301-jffs-compression,v 1.1 2005/03/26 10:33:31 wbx Exp $ -+ * -+ * Copyright (C) 2004, Ferenc Havasi -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version 2 -+ * of the License, or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -+ * -+ */ -+ -+#include <linux/kernel.h> -+#include <linux/fs.h> -+#include <linux/jffs2.h> -+#include <linux/proc_fs.h> -+#include <linux/version.h> -+ -+#include "nodelist.h" -+ -+#include "jffs2_bbc_framework.h" -+ -+struct jffs2_bbc_fs_sb_list { -+ struct super_block *sb; -+ struct jffs2_bbc_fs_sb_list *next; -+}; -+ -+static struct jffs2_bbc_fs_sb_list *sb_list = NULL; -+ -+void jffs2_bbc_proc_init(void); -+void jffs2_bbc_proc_deinit(void); -+ -+void jffs2_bbc_load_model(void *sb_par) { -+ struct jffs2_sb_info *c; -+ //struct jffs2_inode_info *f; -+ struct dentry *config_dentry,*model_dentry; -+ struct qstr config_name,model_name; -+ struct file *config_file,*model_file; -+ char *buff=NULL,*model_buff; -+ int config_size,model_size; -+ int i,prev_i; -+ struct super_block *sb; -+ struct jffs2_bbc_fs_sb_list *sb_l; -+ -+ sb = sb_par; -+ sb_l = jffs2_bbc_malloc_small(sizeof(struct jffs2_bbc_fs_sb_list)); -+ sb_l->sb = sb; -+ sb_l->next = sb_list; -+ sb_list = sb_l; -+ config_name.name = JFFS2_BBC_CONFIG_FILE; -+ config_name.len = strlen(config_name.name); -+ config_name.hash = full_name_hash(config_name.name,config_name.len); -+ config_dentry = d_alloc(sb->s_root,&config_name); -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) -+ sb->s_root->d_inode->i_op->lookup(sb->s_root->d_inode,config_dentry); -+#else -+ sb->s_root->d_inode->i_op->lookup(sb->s_root->d_inode,config_dentry,NULL); -+#endif -+ -+ if (config_dentry->d_inode != NULL) { -+ config_size = config_dentry->d_inode->i_size; -+ //printk("config_file_size=%d\n",config_size); -+ if (config_size > 0) { -+ buff = jffs2_bbc_malloc(config_size+1); -+ config_file = dentry_open(config_dentry,NULL,O_RDONLY); -+ kernel_read(config_file,0,buff,config_size); -+ buff[config_size] = 0; -+ for (prev_i = i = 0 ; i < config_size+1 ; i++) { -+ if (buff[i] == '\n') buff[i]=0; -+ if (buff[i] == 0) { -+ if (prev_i != i) { -+ if ((buff[prev_i] == '-') && (buff[prev_i+1] == 0)) break; -+ printk("reading model file %s... ",buff+prev_i); -+ model_name.name = buff+prev_i; -+ model_name.len = strlen(buff+prev_i); -+ model_name.hash = full_name_hash(model_name.name,model_name.len); -+ model_dentry = d_alloc(sb->s_root,&model_name); -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) -+ sb->s_root->d_inode->i_op->lookup(sb->s_root->d_inode,model_dentry); -+#else -+ sb->s_root->d_inode->i_op->lookup(sb->s_root->d_inode,model_dentry,NULL); -+#endif -+ if (model_dentry->d_inode != NULL) { -+ c = JFFS2_SB_INFO(model_dentry->d_inode->i_sb); -+ //f = JFFS2_INODE_INFO(model_dentry->d_inode); -+ model_size = model_dentry->d_inode->i_size; -+ model_buff = jffs2_bbc_malloc(model_size); -+ model_file = dentry_open(model_dentry,NULL,O_RDONLY); -+ kernel_read(model_file,0,model_buff,model_size); -+ if (jffs2_bbc_model_new(c,model_dentry->d_inode->i_ino,model_buff) != 0) { -+ printk("already loaded.\n"); -+ jffs2_bbc_free(model_buff); -+ } -+ else { -+ printk("done (%d bytes readed from inode %d).\n",model_size,(int)(model_dentry->d_inode->i_ino)); -+ } -+ } -+ else { -+ printk("not found.\n"); -+ } -+ dput(model_dentry); -+ } -+ prev_i = i+1; -+ } -+ } -+ } -+ } -+ dput(config_dentry); -+ if (buff != NULL) jffs2_bbc_free(buff); -+} -+ -+void jffs2_bbc_unload_model(void *sb_par) -+{ -+ struct jffs2_sb_info *c; -+ struct super_block *sb = sb_par; -+ struct jffs2_bbc_fs_sb_list *sb_l,*sb_l2; -+ int done = 0; -+ -+ c = JFFS2_SB_INFO(sb); -+ jffs2_bbc_model_del(c); -+ if (sb_list == NULL) printk("jffs2.bbc: error! NULL sb list!\n"); -+ else { -+ if (sb_list->sb == sb) { -+ jffs2_bbc_free_small(sb_list); -+ sb_list = NULL; -+ done = 1; -+ } -+ else { -+ sb_l = sb_list; -+ while (sb_l->next != NULL) { -+ if (sb_l->next->sb == sb) { -+ sb_l2 = sb_l->next->next; -+ jffs2_bbc_free_small(sb_l->next); -+ sb_l->next = sb_l2; -+ done = 1; -+ } -+ sb_l = sb_l->next; -+ } -+ -+ } -+ if (done == 0) { -+ printk("jffs2.bbc: cannot delete sb from sblist!\n"); -+ } -+ } -+} -+ -+static int jffs2_bbc_get_mounted(void) { -+ struct jffs2_bbc_fs_sb_list *sb_l; -+ int num = 0; -+ -+ sb_l = sb_list; -+ while (sb_l != NULL) { -+ num++; -+ sb_l = sb_l->next; -+ } -+ return num; -+ -+} -+ -+int jffs2_bbc_proc_read(char *buf, char **start, off_t offset, int count, int *eof, void *data) -+{ -+ int len = 0, mode; -+ -+ mode = jffs2_bbc_get_compression_mode(); -+ len += sprintf(buf + len, "BBC version: %s\n", JFFS2_BBC_VERSION); -+ len += sprintf(buf+len,"Mounted jffs2 filesystems: %d\n",jffs2_bbc_get_mounted()); -+ //len += sprintf(buf+len,"actual model file inode: %d\n",jffs2_bbc_model_get_inum()); -+ len += sprintf(buf + len, "Compression mode: "); -+ if (mode == JFFS2_BBC_ZLIB_MODE) -+ len += sprintf(buf + len, "ZLIB mode"); -+ else if (mode == JFFS2_BBC_SIZE_MODE) -+ len += sprintf(buf + len, "SIZE mode"); -+ else if (mode == JFFS2_BBC_FASTR_MODE) -+ len += sprintf(buf + len, "FASTR mode"); -+ else if (mode == JFFS2_BBC_FASTW_MODE) -+ len += sprintf(buf + len, "FASTW mode"); -+ else if (mode == JFFS2_BBC_FASTS_MODE) -+ len += sprintf(buf + len, "FASTS mode"); -+ else if (mode == JFFS2_BBC_DUMMY_MODE) -+ len += sprintf(buf + len, "DUMMY mode"); -+ else if (mode == JFFS2_BBC_MANUAL_MODE) { -+ len += sprintf(buf + len, "MANUAL mode ("); -+ if (jffs2_bbc_get_manual_compressor() != NULL) -+ len += sprintf(buf + len, "%s)", jffs2_bbc_get_manual_compressor()->name); -+ else -+ len += sprintf(buf + len, "ZLIB)"); -+ } -+ else -+ len += sprintf(buf + len, "unknown mode"); -+ len += sprintf(buf + len, "\n"); -+ len += sprintf(buf + len, "%s", jffs2_bbc_get_compr_stats()); -+ len += sprintf(buf + len, "%s", jffs2_bbc_get_model_stats()); -+ len += sprintf(buf + len, "%s", jffs2_bbc_get_mem_stats()); -+ *eof = 1; -+ return len; -+} -+ -+int jffs2_bbc_proc_write(struct file *file, const char *buffer_orig, unsigned long count, void *data) -+{ -+ char *buffer; -+ int i; -+ struct jffs2_bbc_fs_sb_list *sb_l; -+ -+ if (buffer_orig == NULL) return 0; -+ -+ buffer = jffs2_bbc_malloc(count+2); -+ for (i=0;i<count;i++) buffer[i]=buffer_orig[i]; -+ buffer[count] = 0; -+ if ((*buffer == 'z') || (*buffer == 'Z')) { -+ jffs2_bbc_set_compression_mode(JFFS2_BBC_ZLIB_MODE); -+ jffs2_bbc_print1("jffs2.bbc: ZLIB compression mode activated.\n"); -+ jffs2_bbc_free(buffer); -+ return count; -+ } -+ else if ((*buffer == 's') || (*buffer == 'S')) { -+ jffs2_bbc_set_compression_mode(JFFS2_BBC_SIZE_MODE); -+ jffs2_bbc_print1("jffs2.bbc: SIZE compression mode activated.\n"); -+ jffs2_bbc_free(buffer); -+ return count; -+ } -+ else if ((*buffer == 'd') || (*buffer == 'D')) { -+ jffs2_bbc_set_compression_mode(JFFS2_BBC_DUMMY_MODE); -+ jffs2_bbc_print1("jffs2.bbc: DUMMY compression mode activated.\n"); -+ jffs2_bbc_free(buffer); -+ return count; -+ } -+ else if (((*buffer == 'm') || (*buffer == 'M')) && (count >= 3) && (buffer[1] == ':')) { -+ jffs2_bbc_print1("jffs2.bbc: activating MANUAL mode.\n"); -+ jffs2_bbc_set_manual_compressor_by_name(buffer + 2); -+ jffs2_bbc_free(buffer); -+ return count; -+ } -+ else if (((*buffer == '0')) && (count >= 3) && (buffer[1] == ':')) { -+ jffs2_bbc_print1("jffs2.bbc: disabling a compressor... "); -+ if (jffs2_bbc_disable_compressor_by_name(buffer + 2) == 0) { -+ jffs2_bbc_print1("done.\n"); -+ } -+ else { -+ jffs2_bbc_print1("not found.\n"); -+ } -+ jffs2_bbc_free(buffer); -+ return count; -+ } -+ else if (((*buffer == '1')) && (count >= 3) && (buffer[1] == ':')) { -+ jffs2_bbc_print1("jffs2.bbc: enabling a compressor... "); -+ if (jffs2_bbc_enable_compressor_by_name(buffer + 2) == 0) { -+ jffs2_bbc_print1("done.\n"); -+ } -+ else { -+ jffs2_bbc_print1("not found.\n"); -+ } -+ jffs2_bbc_free(buffer); -+ return count; -+ } -+ else if (((*buffer == 'c') || (*buffer == 'C')) && (count >= 3) && (buffer[1] == ':')) { -+ jffs2_bbc_compressor_command_by_name(buffer + 2); -+ jffs2_bbc_free(buffer); -+ return count; -+ } -+ else if ((*buffer == 'r') || (*buffer == 'R')) { -+ jffs2_bbc_print1("jffs2.bbc: reloading model files:\n"); -+ sb_l = sb_list; -+ while (sb_l != NULL) { -+ jffs2_bbc_unload_model(sb_l->sb); -+ jffs2_bbc_load_model(sb_l->sb); -+ sb_l = sb_l->next; -+ } -+ jffs2_bbc_free(buffer); -+ return count; -+ } -+ else if (((buffer[0] == 'f') || (buffer[0] == 'F'))&&((buffer[1] == 'r') || (buffer[1] == 'R'))) { -+ jffs2_bbc_set_compression_mode(JFFS2_BBC_FASTR_MODE); -+ jffs2_bbc_print1("jffs2.bbc: FASTR compression mode activated.\n"); -+ jffs2_bbc_free(buffer); -+ return count; -+ } -+ else if (((buffer[0] == 'f') || (buffer[0] == 'F'))&&((buffer[1] == 'w') || (buffer[1] == 'W'))) { -+ jffs2_bbc_set_compression_mode(JFFS2_BBC_FASTW_MODE); -+ jffs2_bbc_print1("jffs2.bbc: FASTW compression mode activated.\n"); -+ jffs2_bbc_free(buffer); -+ return count; -+ } -+ else if (((buffer[0] == 'f') || (buffer[0] == 'F'))&&((buffer[1] == 's') || (buffer[1] == 'S'))) { -+ jffs2_bbc_set_compression_mode(JFFS2_BBC_FASTS_MODE); -+ jffs2_bbc_print1("jffs2.bbc: FASTS compression mode activated.\n"); -+ jffs2_bbc_free(buffer); -+ return count; -+ } -+ -+ jffs2_bbc_print1("jffs2.bbc: unkown command. Valid commands are:\n" -+ " z = switch to ZLIB compression mode\n" -+ " s = switch to SIZE compression mode\n" -+ " d = switch to DUMMY compression mode\n" -+ " fr = switch to FASTR compression mode\n" -+ " fw = switch to FASTW compression mode\n" -+ " fs = switch to FASTS compression mode\n" -+ " r = reread model files from actual file system\n" -+ " m:compressor_name = switch to MANUAL compression mode\n" -+ " 0:compressor_name = disable a compressor\n" -+ " 1:compressor_name = enable a compressor\n" -+ " c:compressor_name:command = enable a compressor\n"); -+ jffs2_bbc_free(buffer); -+ return count; -+} -+ -+void jffs2_bbc_proc_init() -+{ -+ struct proc_dir_entry *res = create_proc_entry("jffs2_bbc", 0, NULL); -+ jffs2_bbc_compressor_init(); -+ if (res) { -+ res->read_proc = jffs2_bbc_proc_read; -+ res->write_proc = jffs2_bbc_proc_write; -+ } -+} -+ -+void jffs2_bbc_proc_deinit() -+{ -+ jffs2_bbc_compressor_deinit(); -+ remove_proc_entry("jffs2_bbc", NULL); -+} -diff -Nur linux-mips-cvs/fs/jffs2/jffs2_bbc_fs.h linux-mips/fs/jffs2/jffs2_bbc_fs.h ---- linux-mips-cvs/fs/jffs2/jffs2_bbc_fs.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-mips/fs/jffs2/jffs2_bbc_fs.h 2005-02-07 05:08:34.000000000 +0100 -@@ -0,0 +1,30 @@ -+/* -+ * JFFS2 BBC: File System Extension for Linux Kernel - headers -+ * -+ * $Id: 301-jffs-compression,v 1.1 2005/03/26 10:33:31 wbx Exp $ -+ * -+ * Copyright (C) 2004, Ferenc Havasi -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version 2 -+ * of the License, or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -+ * -+ */ -+ -+extern int jffs2_bbc_inode_not_found; -+ -+void jffs2_bbc_load_model(void *sb); -+void jffs2_bbc_unload_model(void *sb); -+ -+void jffs2_bbc_proc_init(void); -+void jffs2_bbc_proc_deinit(void); -diff -Nur linux-mips-cvs/fs/jffs2/jffs2_bbc_lzari_comp.c linux-mips/fs/jffs2/jffs2_bbc_lzari_comp.c ---- linux-mips-cvs/fs/jffs2/jffs2_bbc_lzari_comp.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-mips/fs/jffs2/jffs2_bbc_lzari_comp.c 2005-02-07 05:08:34.000000000 +0100 -@@ -0,0 +1,788 @@ -+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */ -+ -+/* -+ jffs2_bbc_lzari_comp.c -- Lempel-Ziv-Arithmetic coding compression module for jffs2 -+ Copyright (C) 2004 Patrik Kluba -+ Based on the LZARI source included in LDS (lossless datacompression sources) -+ Block-compression and bitstream modifications by Patrik Kluba -+ $Header: /openwrt/openwrt/package/linux/kernel-patches/301-jffs-compression,v 1.1 2005/03/26 10:33:31 wbx Exp $ -+*/ -+ -+/* -+Original copyright follows: -+ -+************************************************************** -+ LZARI.C -- A Data Compression Program -+ (tab = 4 spaces) -+************************************************************** -+ 4/7/1989 Haruhiko Okumura -+ Use, distribute, and modify this program freely. -+ Please send me your improved versions. -+ PC-VAN SCIENCE -+ NIFTY-Serve PAF01022 -+ CompuServe 74050,1022 -+************************************************************** -+ -+LZARI.C (c)1989 by Haruyasu Yoshizaki, Haruhiko Okumura, and Kenji Rikitake. -+All rights reserved. Permission granted for non-commercial use. -+ -+*/ -+ -+/* -+ -+ 2004-02-18 pajko <pajko(AT)halom(DOT)u-szeged(DOT)hu> -+ Removed unused variables and fixed no return value -+ -+ 2004-02-16 pajko <pajko(AT)halom(DOT)u-szeged(DOT)hu> -+ Initial release -+ -+*/ -+ -+/* lzari.c */ -+ -+#define N 4096 /* size of ring buffer */ -+#define F 60 /* upper limit for match_length */ -+#define THRESHOLD 2 /* encode string into position and length -+ if match_length is greater than this */ -+#define NIL N /* index for root of binary search trees */ -+ -+static unsigned char -+ text_buf[N + F - 1]; /* ring buffer of size N, -+ with extra F-1 bytes to facilitate string comparison */ -+static unsigned long match_position, match_length, /* of longest match. These are -+ set by the InsertNode() procedure. */ -+ lson[N + 1], rson[N + 257], dad[N + 1]; /* left & right children & -+ parents -- These constitute binary search trees. */ -+ -+static void InitTree(void) /* Initialize trees */ -+{ -+ unsigned long i; -+ -+ /* For i = 0 to N - 1, rson[i] and lson[i] will be the right and -+ left children of node i. These nodes need not be initialized. -+ Also, dad[i] is the parent of node i. These are initialized to -+ NIL (= N), which stands for 'not used.' -+ For i = 0 to 255, rson[N + i + 1] is the root of the tree -+ for strings that begin with character i. These are initialized -+ to NIL. Note there are 256 trees. */ -+ -+ for (i = N + 1; i <= N + 256; i++) rson[i] = NIL; /* root */ -+ for (i = 0; i < N; i++) dad[i] = NIL; /* node */ -+} -+ -+static void InsertNode(unsigned long r) -+ /* Inserts string of length F, text_buf[r..r+F-1], into one of the -+ trees (text_buf[r]'th tree) and returns the longest-match position -+ and length via the global variables match_position and match_length. -+ If match_length = F, then removes the old node in favor of the new -+ one, because the old one will be deleted sooner. -+ Note r plays double role, as tree node and position in buffer. */ -+{ -+ unsigned long i, p, temp; -+ unsigned char *key; -+ signed long cmp; -+ -+ cmp = 1; key = &text_buf[r]; p = N + 1 + key[0]; -+ rson[r] = lson[r] = NIL; match_length = 0; -+ for ( ; ; ) { -+ if (cmp >= 0) { -+ if (rson[p] != NIL) p = rson[p]; -+ else { rson[p] = r; dad[r] = p; return; } -+ } else { -+ if (lson[p] != NIL) p = lson[p]; -+ else { lson[p] = r; dad[r] = p; return; } -+ } -+ for (i = 1; i < F; i++) -+ if ((cmp = key[i] - text_buf[p + i]) != 0) break; -+ if (i > THRESHOLD) { -+ if (i > match_length) { -+ match_position = (r - p) & (N - 1); -+ if ((match_length = i) >= F) break; -+ } else if (i == match_length) { -+ if ((temp = (r - p) & (N - 1)) < match_position) -+ match_position = temp; -+ } -+ } -+ } -+ dad[r] = dad[p]; lson[r] = lson[p]; rson[r] = rson[p]; -+ dad[lson[p]] = r; dad[rson[p]] = r; -+ if (rson[dad[p]] == p) rson[dad[p]] = r; -+ else lson[dad[p]] = r; -+ dad[p] = NIL; /* remove p */ -+} -+ -+static void DeleteNode(unsigned long p) /* Delete node p from tree */ -+{ -+ unsigned long q; -+ -+ if (dad[p] == NIL) return; /* not in tree */ -+ if (rson[p] == NIL) q = lson[p]; -+ else if (lson[p] == NIL) q = rson[p]; -+ else { -+ q = lson[p]; -+ if (rson[q] != NIL) { -+ do { q = rson[q]; } while (rson[q] != NIL); -+ rson[dad[q]] = lson[q]; dad[lson[q]] = dad[q]; -+ lson[q] = lson[p]; dad[lson[p]] = q; -+ } -+ rson[q] = rson[p]; dad[rson[p]] = q; -+ } -+ dad[q] = dad[p]; -+ if (rson[dad[p]] == p) rson[dad[p]] = q; -+ else lson[dad[p]] = q; -+ dad[p] = NIL; -+} -+ -+/********** Arithmetic Compression **********/ -+ -+/* If you are not familiar with arithmetic compression, you should read -+ I. E. Witten, R. M. Neal, and J. G. Cleary, -+ Communications of the ACM, Vol. 30, pp. 520-540 (1987), -+ from which much have been borrowed. */ -+ -+#define M 15 -+ -+/* Q1 (= 2 to the M) must be sufficiently large, but not so -+ large as the unsigned long 4 * Q1 * (Q1 - 1) overflows. */ -+ -+#define Q1 (1UL << M) -+#define Q2 (2 * Q1) -+#define Q3 (3 * Q1) -+#define Q4 (4 * Q1) -+#define MAX_CUM (Q1 - 1) -+ -+#define N_CHAR (256 - THRESHOLD + F) -+ /* character code = 0, 1, ..., N_CHAR - 1 */ -+ -+static unsigned long char_to_sym[N_CHAR], sym_to_char[N_CHAR + 1]; -+static unsigned long -+ sym_freq[N_CHAR + 1], /* frequency for symbols */ -+ sym_cum[N_CHAR + 1], /* cumulative freq for symbols */ -+ position_cum[N + 1]; /* cumulative freq for positions */ -+ -+static void StartModel(void) /* Initialize model */ -+{ -+ unsigned long ch, sym, i; -+ -+ sym_cum[N_CHAR] = 0; -+ for (sym = N_CHAR; sym >= 1; sym--) { -+ ch = sym - 1; -+ char_to_sym[ch] = sym; sym_to_char[sym] = ch; -+ sym_freq[sym] = 1; -+ sym_cum[sym - 1] = sym_cum[sym] + sym_freq[sym]; -+ } -+ sym_freq[0] = 0; /* sentinel (!= sym_freq[1]) */ -+ position_cum[N] = 0; -+ for (i = N; i >= 1; i--) -+ position_cum[i - 1] = position_cum[i] + 10000 / (i + 200); -+ /* empirical distribution function (quite tentative) */ -+ /* Please devise a better mechanism! */ -+} -+ -+static void UpdateModel(unsigned long sym) -+{ -+ unsigned long c, ch_i, ch_sym; -+ unsigned long i; -+ if (sym_cum[0] >= MAX_CUM) { -+ c = 0; -+ for (i = N_CHAR; i > 0; i--) { -+ sym_cum[i] = c; -+ c += (sym_freq[i] = (sym_freq[i] + 1) >> 1); -+ } -+ sym_cum[0] = c; -+ } -+ for (i = sym; sym_freq[i] == sym_freq[i - 1]; i--) ; -+ if (i < sym) { -+ ch_i = sym_to_char[i]; ch_sym = sym_to_char[sym]; -+ sym_to_char[i] = ch_sym; sym_to_char[sym] = ch_i; -+ char_to_sym[ch_i] = sym; char_to_sym[ch_sym] = i; -+ } -+ sym_freq[i]++; -+ while (--i > 0) sym_cum[i]++; -+ sym_cum[0]++; -+} -+ -+static unsigned long BinarySearchSym(unsigned long x) -+ /* 1 if x >= sym_cum[1], -+ N_CHAR if sym_cum[N_CHAR] > x, -+ i such that sym_cum[i - 1] > x >= sym_cum[i] otherwise */ -+{ -+ unsigned long i, j, k; -+ -+ i = 1; j = N_CHAR; -+ while (i < j) { -+ k = (i + j) / 2; -+ if (sym_cum[k] > x) i = k + 1; else j = k; -+ } -+ return i; -+} -+ -+unsigned long BinarySearchPos(unsigned long x) -+ /* 0 if x >= position_cum[1], -+ N - 1 if position_cum[N] > x, -+ i such that position_cum[i] > x >= position_cum[i + 1] otherwise */ -+{ -+ unsigned long i, j, k; -+ -+ i = 1; j = N; -+ while (i < j) { -+ k = (i + j) / 2; -+ if (position_cum[k] > x) i = k + 1; else j = k; -+ } -+ return i - 1; -+} -+ -+/* modified for block compression */ -+/* on return, srclen will contain the number of successfully compressed bytes -+ and dstlen will contain completed compressed bytes */ -+ -+static int Encode(unsigned char *srcbuf, unsigned char *dstbuf, unsigned long *srclen, -+ unsigned long *dstlen) -+{ -+ unsigned long c, i, len, r, s, last_match_length, sym, range; -+ unsigned long low = 0; -+ unsigned long high = Q4; -+ unsigned long shifts = 0; /* counts for magnifying low and high around Q2 */ -+ unsigned char *ip, *op; -+ unsigned long written = 0; -+ unsigned long read = 0; -+ unsigned char buffer = 0; -+ unsigned char mask = 128; -+ unsigned char *srcend = srcbuf + *srclen; -+ unsigned char *dstend = dstbuf + *dstlen; -+ ip = srcbuf; -+ op = dstbuf; -+ StartModel(); -+ InitTree(); /* initialize trees */ -+ s = 0; r = N - F; -+ for (i = s; i < r; i++) text_buf[i] = ' '; /* Clear the buffer with -+ any character that will appear often. */ -+ for (len = 0; (len < F) && (ip < srcend); len++) -+ text_buf[r + len] = *(ip++); /* Read F bytes into the last F bytes of -+ the buffer */ -+ read = len; -+ for (i = 1; i <= F; i++) InsertNode(r - i); /* Insert the F strings, -+ each of which begins with one or more 'space' characters. Note -+ the order in which these strings are inserted. This way, -+ degenerate trees will be less likely to occur. */ -+ InsertNode(r); /* Finally, insert the whole string just read. The -+ global variables match_length and match_position are set. */ -+ do { -+ if (match_length > len) match_length = len; /* match_length -+ may be spuriously long near the end of text. */ -+ if (match_length <= THRESHOLD) { -+ match_length = 1; /* Not long enough match. Send one byte. */ -+ sym = char_to_sym[text_buf[r]]; -+ range = high - low; -+ high = low + (range * sym_cum[sym - 1]) / sym_cum[0]; -+ low += (range * sym_cum[sym ]) / sym_cum[0]; -+ for ( ; ; ) { -+ if (high <= Q2) { -+ if ((mask >>= 1) == 0) { -+ if (op >= dstend) { -+ *dstlen = written; -+ return -1; -+ } -+ *(op++) = buffer; -+ buffer = 0; -+ mask = 128; -+ written++; -+ *srclen = read; -+ } -+ for ( ; shifts > 0; shifts--) { -+ buffer |= mask; -+ if ((mask >>= 1) == 0) { -+ if (op >= dstend) { -+ *dstlen = written; -+ return -1; -+ } -+ *(op++) = buffer; -+ buffer = 0; -+ mask = 128; -+ written++; -+ *srclen = read; -+ } -+ } -+ } else if (low >= Q2) { -+ buffer |= mask; -+ if ((mask >>= 1) == 0) { -+ if (op >= dstend) { -+ *dstlen = written; -+ return -1; -+ } -+ *(op++) = buffer; -+ buffer = 0; -+ mask = 128; -+ written++; -+ *srclen = read; -+ } -+ for ( ; shifts > 0; shifts--) { -+ if ((mask >>= 1) == 0) { -+ if (op >= dstend) { -+ *dstlen = written; -+ return -1; -+ } -+ *(op++) = buffer; -+ buffer = 0; -+ mask = 128; -+ written++; -+ *srclen = read; -+ } -+ } -+ low -= Q2; -+ high -= Q2; -+ } else if (low >= Q1 && high <= Q3) { -+ shifts++; -+ low -= Q1; -+ high -= Q1; -+ } else break; -+ low += low; high += high; -+ } -+ UpdateModel(sym); -+ } else { -+ sym = char_to_sym[255 - THRESHOLD + match_length]; -+ range = high - low; -+ high = low + (range * sym_cum[sym - 1]) / sym_cum[0]; -+ low += (range * sym_cum[sym ]) / sym_cum[0]; -+ for ( ; ; ) { -+ if (high <= Q2) { -+ if ((mask >>= 1) == 0) { -+ if (op >= dstend) { -+ *dstlen = written; -+ return -1; -+ } -+ *(op++) = buffer; -+ buffer = 0; -+ mask = 128; -+ written++; -+ *srclen = read; -+ } -+ for ( ; shifts > 0; shifts--) { -+ buffer |= mask; -+ if ((mask >>= 1) == 0) { -+ if (op >= dstend) { -+ *dstlen = written; -+ return -1; -+ } -+ *(op++) = buffer; -+ buffer = 0; -+ mask = 128; -+ written++; -+ *srclen = read; -+ } -+ } -+ } else if (low >= Q2) { -+ buffer |= mask; -+ if ((mask >>= 1) == 0) { -+ if (op >= dstend) { -+ *dstlen = written; -+ return -1; -+ } -+ *(op++) = buffer; -+ buffer = 0; -+ mask = 128; -+ written++; -+ *srclen = read; -+ } -+ for ( ; shifts > 0; shifts--) { -+ if ((mask >>= 1) == 0) { -+ if (op >= dstend) { -+ *dstlen = written; -+ return -1; -+ } -+ *(op++) = buffer; -+ buffer = 0; -+ mask = 128; -+ written++; -+ *srclen = read; -+ } -+ } -+ low -= Q2; -+ high -= Q2; -+ } else if (low >= Q1 && high <= Q3) { -+ shifts++; -+ low -= Q1; -+ high -= Q1; -+ } else break; -+ low += low; high += high; -+ } -+ UpdateModel(sym); -+ range = high - low; -+ high = low + (range * position_cum[match_position - 1]) / position_cum[0]; -+ low += (range * position_cum[match_position ]) / position_cum[0]; -+ for ( ; ; ) { -+ if (high <= Q2) { -+ if ((mask >>= 1) == 0) { -+ if (op >= dstend) { -+ *dstlen = written; -+ return -1; -+ } -+ *(op++) = buffer; -+ buffer = 0; -+ mask = 128; -+ written++; -+ *srclen = read; -+ } -+ for ( ; shifts > 0; shifts--) { -+ buffer |= mask; -+ if ((mask >>= 1) == 0) { -+ if (op >= dstend) { -+ *dstlen = written; -+ return -1; -+ } -+ *(op++) = buffer; -+ buffer = 0; -+ mask = 128; -+ written++; -+ *srclen = read; -+ } -+ } -+ } else { -+ if (low >= Q2) { -+ buffer |= mask; -+ if ((mask >>= 1) == 0) { -+ if (op >= dstend) { -+ *dstlen = written; -+ return -1; -+ } -+ *(op++) = buffer; -+ buffer = 0; -+ mask = 128; -+ written++; -+ *srclen = read; -+ } -+ for ( ; shifts > 0; shifts--) { -+ if ((mask >>= 1) == 0) { -+ if (op >= dstend) { -+ *dstlen = written; -+ return -1; -+ } -+ *(op++) = buffer; -+ buffer = 0; -+ mask = 128; -+ written++; -+ *srclen = read; -+ } -+ } -+ low -= Q2; -+ high -= Q2; -+ } else { -+ if ((low >= Q1) && (high <= Q3)) { -+ shifts++; -+ low -= Q1; -+ high -= Q1; -+ } else { -+ break; -+ } -+ } -+ } -+ low += low; -+ high += high; -+ } -+ } -+ last_match_length = match_length; -+ for (i = 0; (i < last_match_length) && (ip < srcend); i++) { -+ c = *(ip++); -+ DeleteNode(s); -+ text_buf[s] = c; -+ if (s < F - 1) -+ text_buf[s + N] = c; -+ s = (s + 1) & (N - 1); -+ r = (r + 1) & (N - 1); -+ InsertNode(r); -+ } -+ read += i; -+ while (i++ < last_match_length) { -+ DeleteNode(s); -+ s = (s + 1) & (N - 1); -+ r = (r + 1) & (N - 1); -+ if (--len) InsertNode(r); -+ } -+ } while (len > 0); -+ shifts++; -+ if (low < Q1) { -+ if ((mask >>= 1) == 0) { -+ if (op >= dstend) { -+ *dstlen = written; -+ return -1; -+ } -+ *(op++) = buffer; -+ buffer = 0; -+ mask = 128; -+ written++; -+ *srclen = read; -+ } -+ for ( ; shifts > 0; shifts--) { -+ buffer |= mask; -+ if ((mask >>= 1) == 0) { -+ if (op >= dstend) { -+ *dstlen = written; -+ return -1; -+ } -+ *(op++) = buffer; -+ buffer = 0; -+ mask = 128; -+ written++; -+ *srclen = read; -+ } -+ } -+ } else { -+ buffer |= mask; -+ if ((mask >>= 1) == 0) { -+ if (op >= dstend) { -+ *dstlen = written; -+ return -1; -+ } -+ *(op++) = buffer; -+ buffer = 0; -+ mask = 128; -+ written++; -+ *srclen = read; -+ } -+ for ( ; shifts > 0; shifts--) { -+ if ((mask >>= 1) == 0) { -+ if (op >= dstend) { -+ *dstlen = written; -+ return -1; -+ } -+ *(op++) = buffer; -+ buffer = 0; -+ mask = 128; -+ written++; -+ *srclen = read; -+ } -+ } -+ } -+ for (i = 0; i < 7; i++) { -+ if ((mask >>= 1) == 0) { -+ if (op >= dstend) { -+ *dstlen = written; -+ return -1; -+ } -+ *(op++) = buffer; -+ buffer = 0; -+ mask = 128; -+ written++; -+ *srclen = read; -+ } -+ } -+ *dstlen = written; -+ return 0; -+} -+ -+static int Decode(unsigned char *srcbuf, unsigned char *dstbuf, unsigned long srclen, -+ unsigned long dstlen) /* Just the reverse of Encode(). */ -+{ -+ unsigned long i, r, j, k, c, range, sym; -+ unsigned char *ip, *op; -+ unsigned char *srcend = srcbuf + srclen; -+ unsigned char *dstend = dstbuf + dstlen; -+ unsigned char buffer = 0; -+ unsigned char mask = 0; -+ unsigned long low = 0; -+ unsigned long high = Q4; -+ unsigned long value = 0; -+ ip = srcbuf; -+ op = dstbuf; -+ for (i = 0; i < M + 2; i++) { -+ value *= 2; -+ if ((mask >>= 1) == 0) { -+ buffer = (ip >= srcend) ? 0 : *(ip++); -+ mask = 128; -+ } -+ value += ((buffer & mask) != 0); -+ } -+ StartModel(); -+ for (i = 0; i < N - F; i++) text_buf[i] = ' '; -+ r = N - F; -+ while (op < dstend) { -+ range = high - low; -+ sym = BinarySearchSym((unsigned long) -+ (((value - low + 1) * sym_cum[0] - 1) / range)); -+ high = low + (range * sym_cum[sym - 1]) / sym_cum[0]; -+ low += (range * sym_cum[sym ]) / sym_cum[0]; -+ for ( ; ; ) { -+ if (low >= Q2) { -+ value -= Q2; low -= Q2; high -= Q2; -+ } else if (low >= Q1 && high <= Q3) { -+ value -= Q1; low -= Q1; high -= Q1; -+ } else if (high > Q2) break; -+ low += low; high += high; -+ value *= 2; -+ if ((mask >>= 1) == 0) { -+ buffer = (ip >= srcend) ? 0 : *(ip++); -+ mask = 128; -+ } -+ value += ((buffer & mask) != 0); -+ } -+ c = sym_to_char[sym]; -+ UpdateModel(sym); -+ if (c < 256) { -+ if (op >= dstend) return -1; -+ *(op++) = c; -+ text_buf[r++] = c; -+ r &= (N - 1); -+ } else { -+ j = c - 255 + THRESHOLD; -+ range = high - low; -+ i = BinarySearchPos((unsigned long) -+ (((value - low + 1) * position_cum[0] - 1) / range)); -+ high = low + (range * position_cum[i ]) / position_cum[0]; -+ low += (range * position_cum[i + 1]) / position_cum[0]; -+ for ( ; ; ) { -+ if (low >= Q2) { -+ value -= Q2; low -= Q2; high -= Q2; -+ } else if (low >= Q1 && high <= Q3) { -+ value -= Q1; low -= Q1; high -= Q1; -+ } else if (high > Q2) break; -+ low += low; high += high; -+ value *= 2; -+ if ((mask >>= 1) == 0) { -+ buffer = (ip >= srcend) ? 0 : *(ip++); -+ mask = 128; -+ } -+ value += ((buffer & mask) != 0); -+ } -+ i = (r - i - 1) & (N - 1); -+ for (k = 0; k < j; k++) { -+ c = text_buf[(i + k) & (N - 1)]; -+ if (op >= dstend) return -1; -+ *(op++) = c; -+ text_buf[r++] = c; -+ r &= (N - 1); -+ } -+ } -+ } -+ return 0; -+} -+ -+/* interface to jffs2 bbc follows */ -+ -+#include "jffs2_bbc_framework.h" -+ -+#define JFFS2_BBC_LZARI_BLOCK_SIGN {0x73, 0x9a, 0x1c, 0x4d} -+ -+static int -+jffs2_bbc_lzari_compressor_init (void); -+ -+static void -+jffs2_bbc_lzari_compressor_deinit (void); -+ -+static int -+jffs2_bbc_lzari_compress (void *model, unsigned char *input, -+ unsigned char *output, unsigned long *sourcelen, -+ unsigned long *dstlen); -+ -+static int -+jffs2_bbc_lzari_estimate (void *model, unsigned char *input, -+ unsigned long sourcelen, unsigned long *dstlen, -+ unsigned long *readtime, unsigned long *writetime); -+ -+static int -+jffs2_bbc_lzari_decompress (void *model, unsigned char *input, -+ unsigned char *output, unsigned long sourcelen, -+ unsigned long dstlen); -+ -+static char * -+jffs2_bbc_lzari_proc_info (void); -+ -+static int -+jffs2_bbc_lzari_proc_command (char *command); -+ -+struct jffs2_bbc_compressor_type jffs2_bbc_lzari = { -+ "lzari", -+ 0, -+ JFFS2_BBC_LZARI_BLOCK_SIGN, -+ jffs2_bbc_lzari_compressor_init, -+ NULL, -+ NULL, -+ jffs2_bbc_lzari_compressor_deinit, -+ jffs2_bbc_lzari_compress, -+ jffs2_bbc_lzari_estimate, -+ jffs2_bbc_lzari_decompress, -+ jffs2_bbc_lzari_proc_info, -+ jffs2_bbc_lzari_proc_command -+}; -+ -+static int -+jffs2_bbc_lzari_compressor_init (void) -+{ -+ return 0; -+} -+ -+static void -+jffs2_bbc_lzari_compressor_deinit (void) -+{ -+} -+ -+static int -+jffs2_bbc_lzari_compress (void *model, unsigned char *input, -+ unsigned char *output, unsigned long *sourcelen, -+ unsigned long *dstlen) -+{ -+ int retval; -+ unsigned long dst = *dstlen; -+ *(output++) = jffs2_bbc_lzari.block_sign[0]; -+ *(output++) = jffs2_bbc_lzari.block_sign[1]; -+ dst -= 2; -+ retval = Encode(input, output, sourcelen, &dst); -+ dst += 2; -+ *dstlen = dst; -+ return retval; -+} -+ -+static int -+jffs2_bbc_lzari_estimate (void *model, unsigned char *input, -+ unsigned long sourcelen, unsigned long *dstlen, -+ unsigned long *readtime, unsigned long *writetime) -+{ -+ *dstlen = sourcelen / 2; -+ *readtime = JFFS2_BBC_ZLIB_READ_TIME * 15; -+ *writetime = JFFS2_BBC_ZLIB_WRITE_TIME * 7; -+ return 0; -+} -+ -+static int -+jffs2_bbc_lzari_decompress (void *model, unsigned char *input, -+ unsigned char *output, unsigned long sourcelen, -+ unsigned long dstlen) -+{ -+ if ( ( *(input++) != (unsigned char)jffs2_bbc_lzari.block_sign[0] ) || -+ ( *(input++) != (unsigned char)jffs2_bbc_lzari.block_sign[1] ) -+ ) { -+ return -1; -+ } else { -+ return Decode(input, output, sourcelen - 2, dstlen); -+ } -+} -+ -+static char * -+jffs2_bbc_lzari_proc_info (void) -+{ -+ return "Lempel-Ziv-Arithmetic coding compression module"; -+} -+ -+static int -+jffs2_bbc_lzari_proc_command (char *command) -+{ -+ return 0; -+} -+ -+struct jffs2_bbc_compressor_type * -+jffs2_bbc_lzari_init (int mode) -+{ -+ if (jffs2_bbc_register_compressor (&jffs2_bbc_lzari) == 0) -+ { -+ return &jffs2_bbc_lzari; -+ } -+ else -+ { -+ return NULL; -+ } -+} -+ -+void -+jffs2_bbc_lzari_deinit (void) -+{ -+ jffs2_bbc_unregister_compressor (&jffs2_bbc_lzari); -+} -diff -Nur linux-mips-cvs/fs/jffs2/jffs2_bbc_lzhd_comp.c linux-mips/fs/jffs2/jffs2_bbc_lzhd_comp.c ---- linux-mips-cvs/fs/jffs2/jffs2_bbc_lzhd_comp.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-mips/fs/jffs2/jffs2_bbc_lzhd_comp.c 2005-02-07 05:08:34.000000000 +0100 -@@ -0,0 +1,747 @@ -+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */ -+ -+/* -+ jffs2_bbc_lzhd_comp.c -- Lempel-Ziv-(dynamic) Huffman compression module for jffs2 -+ Copyright (C) 2004 Patrik Kluba -+ Based on the LZHUF source included in LDS (lossless datacompression sources) -+ Block-compression and bitstream modifications by Patrik Kluba -+ $Header: /openwrt/openwrt/package/linux/kernel-patches/301-jffs-compression,v 1.1 2005/03/26 10:33:31 wbx Exp $ -+*/ -+ -+/* -+Original copyright follows: -+ -+************************************************************** -+ lzhuf.c -+ written by Haruyasu Yoshizaki 11/20/1988 -+ some minor changes 4/6/1989 -+ comments translated by Haruhiko Okumura 4/7/1989 -+************************************************************** -+ -+LZHUF.C (c)1989 by Haruyasu Yoshizaki, Haruhiko Okumura, and Kenji Rikitake. -+All rights reserved. Permission granted for non-commercial use. -+ -+*/ -+ -+/* -+ -+ 2004-02-18 pajko <pajko(AT)halom(DOT)u-szeged(DOT)hu> -+ Replaced name lzh-d with lzhd -+ Fixed no return value -+ -+ 2004-02-16 pajko <pajko(AT)halom(DOT)u-szeged(DOT)hu> -+ Initial release -+ -+*/ -+ -+/* required because of memmove */ -+#ifndef __KERNEL__ -+ #include <string.h> -+#else -+ #include <linux/string.h> -+#endif -+ -+/* lzhuf.c */ -+ -+#define N 4096 /* size of ring buffer */ -+#define F 60 /* upper limit for match_length */ -+#define THRESHOLD 2 /* encode string into position and length -+ if match_length is greater than this */ -+#define NIL N /* index for root of binary search trees */ -+ -+static unsigned char -+ text_buf[N + F - 1]; /* ring buffer of size N, -+ with extra F-1 bytes to facilitate string comparison */ -+static unsigned long match_position, match_length, /* of longest match. These are -+ set by the InsertNode() procedure. */ -+ lson[N + 1], rson[N + 257], dad[N + 1]; /* left & right children & -+ parents -- These constitute binary search trees. */ -+ -+static void InitTree(void) /* initialize trees */ -+{ -+ unsigned long i; -+ -+ /* For i = 0 to N - 1, rson[i] and lson[i] will be the right and -+ left children of node i. These nodes need not be initialized. -+ Also, dad[i] is the parent of node i. These are initialized to -+ NIL (= N), which stands for 'not used.' -+ For i = 0 to 255, rson[N + i + 1] is the root of the tree -+ for strings that begin with character i. These are initialized -+ to NIL. Note there are 256 trees. */ -+ -+ for (i = N + 1; i <= N + 256; i++) rson[i] = NIL; -+ for (i = 0; i < N; i++) dad[i] = NIL; -+} -+ -+static void InsertNode(unsigned long r) -+ /* Inserts string of length F, text_buf[r..r+F-1], into one of the -+ trees (text_buf[r]'th tree) and returns the longest-match position -+ and length via the global variables match_position and match_length. -+ If match_length = F, then removes the old node in favor of the new -+ one, because the old one will be deleted sooner. -+ Note r plays double role, as tree node and position in buffer. */ -+{ -+ unsigned long i, p, c; -+ signed long cmp; -+ unsigned char *key; -+ -+ cmp = 1; key = &text_buf[r]; p = N + 1 + key[0]; -+ rson[r] = lson[r] = NIL; match_length = 0; -+ for ( ; ; ) { -+ if (cmp >= 0) { -+ if (rson[p] != NIL) p = rson[p]; -+ else { rson[p] = r; dad[r] = p; return; } -+ } else { -+ if (lson[p] != NIL) p = lson[p]; -+ else { lson[p] = r; dad[r] = p; return; } -+ } -+ for (i = 1; i < F; i++) -+ if ((cmp = key[i] - text_buf[p + i]) != 0) break; -+ if (i > THRESHOLD) { -+ if (i > match_length) { -+ match_position = ((r - p) & (N - 1)) - 1; -+ if ((match_length = i) >= F) break; -+ } -+ if (i == match_length) { -+ if ((c = ((r - p) & (N - 1)) - 1) < match_position) { -+ match_position = c; -+ } -+ } -+ } -+ } -+ dad[r] = dad[p]; lson[r] = lson[p]; rson[r] = rson[p]; -+ dad[lson[p]] = r; dad[rson[p]] = r; -+ if (rson[dad[p]] == p) rson[dad[p]] = r; -+ else lson[dad[p]] = r; -+ dad[p] = NIL; /* remove p */ -+} -+ -+static void DeleteNode(unsigned long p) /* deletes node p from tree */ -+{ -+ unsigned long q; -+ -+ if (dad[p] == NIL) return; /* not in tree */ -+ if (rson[p] == NIL) q = lson[p]; -+ else if (lson[p] == NIL) q = rson[p]; -+ else { -+ q = lson[p]; -+ if (rson[q] != NIL) { -+ do { q = rson[q]; } while (rson[q] != NIL); -+ rson[dad[q]] = lson[q]; dad[lson[q]] = dad[q]; -+ lson[q] = lson[p]; dad[lson[p]] = q; -+ } -+ rson[q] = rson[p]; dad[rson[p]] = q; -+ } -+ dad[q] = dad[p]; -+ if (rson[dad[p]] == p) rson[dad[p]] = q; else lson[dad[p]] = q; -+ dad[p] = NIL; -+} -+ -+/* Huffman coding */ -+ -+#define N_CHAR (256 - THRESHOLD + F) -+ /* kinds of characters (character code = 0..N_CHAR-1) */ -+#define T (N_CHAR * 2 - 1) /* size of table */ -+#define R (T - 1) /* position of root */ -+#define MAX_FREQ 0x8000 /* updates tree when the */ -+ /* root frequency comes to this value. */ -+ -+typedef unsigned long uchar; // much-much faster -+ -+/* table for encoding and decoding the upper 6 bits of position */ -+ -+/* for encoding */ -+static uchar p_len[64] = { -+ 0x03, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, -+ 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x06, -+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, -+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, -+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, -+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, -+ 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, -+ 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08 -+}; -+ -+static uchar p_code[64] = { -+ 0x00, 0x20, 0x30, 0x40, 0x50, 0x58, 0x60, 0x68, -+ 0x70, 0x78, 0x80, 0x88, 0x90, 0x94, 0x98, 0x9C, -+ 0xA0, 0xA4, 0xA8, 0xAC, 0xB0, 0xB4, 0xB8, 0xBC, -+ 0xC0, 0xC2, 0xC4, 0xC6, 0xC8, 0xCA, 0xCC, 0xCE, -+ 0xD0, 0xD2, 0xD4, 0xD6, 0xD8, 0xDA, 0xDC, 0xDE, -+ 0xE0, 0xE2, 0xE4, 0xE6, 0xE8, 0xEA, 0xEC, 0xEE, -+ 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, -+ 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF -+}; -+ -+/* for decoding */ -+static uchar d_code[256] = { -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, -+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, -+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, -+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, -+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, -+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, -+ 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, -+ 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, -+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, -+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, -+ 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, -+ 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, -+ 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, -+ 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, -+ 0x0C, 0x0C, 0x0C, 0x0C, 0x0D, 0x0D, 0x0D, 0x0D, -+ 0x0E, 0x0E, 0x0E, 0x0E, 0x0F, 0x0F, 0x0F, 0x0F, -+ 0x10, 0x10, 0x10, 0x10, 0x11, 0x11, 0x11, 0x11, -+ 0x12, 0x12, 0x12, 0x12, 0x13, 0x13, 0x13, 0x13, -+ 0x14, 0x14, 0x14, 0x14, 0x15, 0x15, 0x15, 0x15, -+ 0x16, 0x16, 0x16, 0x16, 0x17, 0x17, 0x17, 0x17, -+ 0x18, 0x18, 0x19, 0x19, 0x1A, 0x1A, 0x1B, 0x1B, -+ 0x1C, 0x1C, 0x1D, 0x1D, 0x1E, 0x1E, 0x1F, 0x1F, -+ 0x20, 0x20, 0x21, 0x21, 0x22, 0x22, 0x23, 0x23, -+ 0x24, 0x24, 0x25, 0x25, 0x26, 0x26, 0x27, 0x27, -+ 0x28, 0x28, 0x29, 0x29, 0x2A, 0x2A, 0x2B, 0x2B, -+ 0x2C, 0x2C, 0x2D, 0x2D, 0x2E, 0x2E, 0x2F, 0x2F, -+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, -+ 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, -+}; -+ -+static uchar d_len[256] = { -+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, -+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, -+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, -+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, -+ 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, -+ 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, -+ 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, -+ 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, -+ 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, -+ 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, -+ 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, -+ 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, -+ 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, -+ 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, -+ 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, -+ 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, -+ 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, -+ 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, -+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, -+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, -+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, -+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, -+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, -+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, -+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, -+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, -+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, -+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, -+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, -+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, -+ 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, -+ 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, -+}; -+ -+static unsigned long freq[T + 1]; /* frequency table */ -+ -+static unsigned long prnt[T + N_CHAR]; /* pointers to parent nodes, except for the */ -+ /* elements [T..T + N_CHAR - 1] which are used to get */ -+ /* the positions of leaves corresponding to the codes. */ -+ -+static unsigned long son[T]; /* pointers to child nodes (son[], son[] + 1) */ -+ -+/* initialization of tree */ -+ -+static void StartHuff(void) -+{ -+ unsigned long i, j; -+ -+ for (i = 0; i < N_CHAR; i++) { -+ freq[i] = 1; -+ son[i] = i + T; -+ prnt[i + T] = i; -+ } -+ i = 0; j = N_CHAR; -+ while (j <= R) { -+ freq[j] = freq[i] + freq[i + 1]; -+ son[j] = i; -+ prnt[i] = prnt[i + 1] = j; -+ i += 2; j++; -+ } -+ freq[T] = 0xffff; -+ prnt[R] = 0; -+} -+ -+/* reconstruction of tree */ -+ -+static void reconst(void) -+{ -+ unsigned long f, l, i, j, k; -+ -+ /* collect leaf nodes in the first half of the table */ -+ /* and replace the freq by (freq + 1) / 2. */ -+ j = 0; -+ for (i = 0; i < T; i++) { -+ if (son[i] >= T) { -+ freq[j] = (freq[i] + 1) / 2; -+ son[j] = son[i]; -+ j++; -+ } -+ } -+ /* begin constructing tree by connecting sons */ -+ for (i = 0, j = N_CHAR; j < T; i += 2, j++) { -+ k = i + 1; -+ f = freq[j] = freq[i] + freq[k]; -+ for (k = j - 1; f < freq[k]; k--); -+ k++; -+ l = (j - k) * 2; -+ memmove(&freq[k + 1], &freq[k], l*sizeof(unsigned long)); -+ freq[k] = f; -+ memmove(&son[k + 1], &son[k], l*sizeof(unsigned long)); -+ son[k] = i; -+ } -+ /* connect prnt */ -+ for (i = 0; i < T; i++) { -+ if ((k = son[i]) >= T) { -+ prnt[k] = i; -+ } else { -+ prnt[k] = prnt[k + 1] = i; -+ } -+ } -+} -+ -+/* increment frequency of given code by one, and update tree */ -+ -+static void update(unsigned long c) -+{ -+ unsigned long i, j, k, l; -+ -+ if (freq[R] == MAX_FREQ) { -+ reconst(); -+ } -+ c = prnt[c + T]; -+ do { -+ k = ++freq[c]; -+ -+ /* if the order is disturbed, exchange nodes */ -+ if (k > freq[l = c + 1]) { -+ while (k > freq[++l]); -+ l--; -+ freq[c] = freq[l]; -+ freq[l] = k; -+ -+ i = son[c]; -+ prnt[i] = l; -+ if (i < T) prnt[i + 1] = l; -+ -+ j = son[l]; -+ son[l] = i; -+ -+ prnt[j] = c; -+ if (j < T) prnt[j + 1] = c; -+ son[c] = j; -+ -+ c = l; -+ } -+ } while (c = prnt[c]); /* repeat up to root */ -+} -+ -+/* modified for block compression */ -+/* on return, srclen will contain the number of successfully compressed bytes -+ and dstlen will contain completed compressed bytes */ -+ -+static int Encode(unsigned char *srcbuf, unsigned char *dstbuf, unsigned long *srclen, -+ unsigned long *dstlen) -+{ -+ unsigned long c, i, j, k, len, r, s, last_match_length, code_buf_ptr; -+ unsigned char code_buf[17], mask; -+ unsigned char *ip, *op; -+ unsigned long written = 0; -+ unsigned long read = 0; -+ unsigned short putbuf = 0; -+ uchar putlen = 0; -+ unsigned char *srcend = srcbuf + *srclen; -+ unsigned char *dstend = dstbuf + *dstlen; -+ ip = srcbuf; -+ op = dstbuf; -+ StartHuff(); -+ InitTree(); /* initialize trees */ -+ code_buf[0] = 0; /* code_buf[1..16] saves eight units of code, and -+ code_buf[0] works as eight flags, "1" representing that the unit -+ is an unencoded letter (1 byte), "0" a position-and-length pair -+ (2 bytes). Thus, eight units require at most 16 bytes of code. */ -+ code_buf_ptr = mask = 1; -+ s = 0; r = N - F; -+ for (i = s; i < r; i++) text_buf[i] = ' '; /* Clear the buffer with -+ any character that will appear often. */ -+ for (len = 0; (len < F) && (ip < srcend); len++) -+ text_buf[r + len] = *(ip++); /* Read F bytes into the last F bytes of -+ the buffer */ -+ read = len; -+ for (i = 1; i <= F; i++) InsertNode(r - i); /* Insert the F strings, -+ each of which begins with one or more 'space' characters. Note -+ the order in which these strings are inserted. This way, -+ degenerate trees will be less likely to occur. */ -+ InsertNode(r); /* Finally, insert the whole string just read. The -+ global variables match_length and match_position are set. */ -+ do { -+ if (match_length > len) match_length = len; /* match_length -+ may be spuriously long near the end of text. */ -+ if (match_length <= THRESHOLD) { -+ match_length = 1; /* Not long enough match. Send one byte. */ -+ c = text_buf[r]; -+ i = 0; j = 0; k = prnt[c + T]; -+ do { -+ i >>= 1; -+ /* if node's address is odd-numbered, choose bigger brother node */ -+ if (k & 1) i |= 0x8000; -+ j++; -+ } while ((k = prnt[k]) != R); -+ putbuf |= i >> putlen; -+ if ((putlen += j) >= 8) { -+ if (op >= dstend) { -+ *dstlen = written; -+ return -1; -+ } -+ *(op++) = putbuf >> 8; -+ if ((putlen -= 8) >= 8) { -+ if (op >= dstend) { -+ *dstlen = written; -+ return -1; -+ } -+ *(op++) = putbuf; -+ written += 2; -+ putlen -= 8; -+ putbuf = i << (j - putlen); /**warm**/ -+ } else { -+ putbuf <<= 8; -+ written++; -+ } -+ *srclen = read; -+ } -+ update(c); -+ } else { -+ c = 255 - THRESHOLD + match_length; -+ i = 0; j = 0; k = prnt[c + T]; -+ do { -+ i >>= 1; -+ /* if node's address is odd-numbered, choose bigger brother node */ -+ if (k & 1) i |= 0x8000; -+ j++; -+ } while ((k = prnt[k]) != R); -+ putbuf |= i >> putlen; -+ if ((putlen += j) >= 8) { -+ if (op >= dstend) { -+ *dstlen = written; -+ return -1; -+ } -+ *(op++) = putbuf >> 8; -+ if ((putlen -= 8) >= 8) { -+ if (op >= dstend) { -+ *dstlen = written; -+ return -1; -+ } -+ *(op++) = putbuf; -+ written += 2; -+ putlen -= 8; -+ putbuf = i << (j - putlen); /**warm**/ -+ } else { -+ putbuf <<= 8; -+ written++; -+ } -+ *srclen = read; -+ } -+ update(c); -+ j = p_len[match_position >> 6]; -+ i = p_code[match_position >> 6] << 8; -+ putbuf |= i >> putlen; -+ if ((putlen += j) >= 8) { -+ if (op >= dstend) { -+ *dstlen = written; -+ return -1; -+ } -+ *(op++) = putbuf >> 8; -+ if ((putlen -= 8) >= 8) { -+ if (op >= dstend) { -+ *dstlen = written; -+ return -1; -+ } -+ *(op++) = putbuf; -+ written += 2; -+ putlen -= 8; -+ putbuf = i << (j - putlen); /**hot**/ -+ } else { -+ putbuf <<= 8; -+ written++; -+ } -+ *srclen = read; -+ } -+ j = 6; -+ i = (match_position & 0x3f) << 10; -+ putbuf |= i >> putlen; -+ if ((putlen += j) >= 8) { -+ if (op >= dstend) { -+ *dstlen = written; -+ return -1; -+ } -+ *(op++) = putbuf >> 8; -+ if ((putlen -= 8) >= 8) { -+ if (op >= dstend) { -+ *dstlen = written; -+ return -1; -+ } -+ *(op++) = putbuf; -+ written += 2; -+ putlen -= 8; -+ putbuf = i << (j - putlen); /**hot**/ -+ } else { -+ putbuf <<= 8; -+ written++; -+ } -+ *srclen = read; -+ } -+ } -+ last_match_length = match_length; -+ for (i = 0; (i < last_match_length) && (ip < srcend); i++) { -+ c = *(ip++); -+ DeleteNode(s); -+ text_buf[s] = c; -+ if (s < F - 1) -+ text_buf[s + N] = c; -+ s = (s + 1) & (N - 1); -+ r = (r + 1) & (N - 1); -+ InsertNode(r); -+ } -+ read += i; -+ while (i++ < last_match_length) { -+ DeleteNode(s); -+ s = (s + 1) & (N - 1); -+ r = (r + 1) & (N - 1); -+ if (--len) InsertNode(r); -+ } -+ } while (len > 0); -+ if (putlen) { -+ if (op >= dstend) { -+ *dstlen = written; -+ return -1; -+ } -+ *(op++) = putbuf >> 8; -+ written++; -+ *srclen = read; -+ } -+ *dstlen = written; -+ return 0; -+} -+ -+static int Decode(unsigned char *srcbuf, unsigned char *dstbuf, unsigned long srclen, -+ unsigned long dstlen) /* Just the reverse of Encode(). */ -+{ -+ unsigned long i, r, j, k, c; -+ unsigned char *ip, *op; -+ unsigned char *srcend = srcbuf + srclen; -+ unsigned char *dstend = dstbuf + dstlen; -+ unsigned short getbuf = 0; -+ uchar getlen = 0; -+ ip = srcbuf; -+ op = dstbuf; -+ StartHuff(); -+ for (i = 0; i < N - F; i++) text_buf[i] = ' '; -+ r = N - F; -+ while (op < dstend) { -+ c = son[R]; -+ /* travel from root to leaf, */ -+ /* choosing the smaller child node (son[]) if the read bit is 0, */ -+ /* the bigger (son[]+1} if 1 */ -+ while (c < T) { -+ while (getlen <= 8) { -+ unsigned short t; -+ t = (ip >= srcend) ? 0 : *(ip++); -+ getbuf |= t << (8 - getlen); -+ getlen += 8; -+ } -+ c += ((signed short)getbuf < 0); -+ getbuf <<= 1; -+ getlen--; -+ c = son[c]; -+ } -+ c -= T; -+ update(c); -+ if (c < 256) { -+ if (op >= dstend) return -1; -+ *(op++) = c; -+ text_buf[r++] = c; -+ r &= (N - 1); -+ } else { -+ j = c - 255 + THRESHOLD; -+ while (getlen <= 8) { -+ unsigned short t; -+ t = (ip >= srcend) ? 0 : *(ip++); -+ getbuf |= t << (8 - getlen); -+ getlen += 8; -+ } -+ i = getbuf >> 8; -+ getbuf <<= 8; -+ getlen -= 8; -+ c = d_code[i] << 6; -+ k = d_len[i]; -+ /* read lower 6 bits verbatim */ -+ k -= 2; -+ while (k--) { -+ while (getlen <= 8) { -+ unsigned short t; -+ t = (ip >= srcend) ? 0 : *(ip++); -+ getbuf |= t << (8 - getlen); -+ getlen += 8; -+ } -+ i = (i << 1) + ((signed short)getbuf < 0); -+ getbuf <<= 1; -+ getlen--; -+ } -+ i = c | (i & 0x3F); -+ i = r - i - 1; -+ i &= (N - 1); -+ for (k = 0; k < j; k++) { -+ c = text_buf[(i + k) & (N - 1)]; -+ if (op >= dstend) return -1; -+ *(op++) = c; -+ text_buf[r++] = c; -+ r &= (N - 1); -+ } -+ } -+ } -+ return 0; -+} -+ -+/* interface to jffs2 bbc follows */ -+ -+#include "jffs2_bbc_framework.h" -+ -+ -+#define JFFS2_BBC_LZHD_BLOCK_SIGN {0x3a, 0x98, 0xf7, 0xda} -+ -+static int -+jffs2_bbc_lzhd_compressor_init (void); -+ -+static void -+jffs2_bbc_lzhd_compressor_deinit (void); -+ -+static int -+jffs2_bbc_lzhd_compress (void *model, unsigned char *input, -+ unsigned char *output, unsigned long *sourcelen, -+ unsigned long *dstlen); -+ -+static int -+jffs2_bbc_lzhd_estimate (void *model, unsigned char *input, -+ unsigned long sourcelen, unsigned long *dstlen, -+ unsigned long *readtime, unsigned long *writetime); -+ -+static int -+jffs2_bbc_lzhd_decompress (void *model, unsigned char *input, -+ unsigned char *output, unsigned long sourcelen, -+ unsigned long dstlen); -+ -+static char * -+jffs2_bbc_lzhd_proc_info (void); -+ -+static int -+jffs2_bbc_lzhd_proc_command (char *command); -+ -+struct jffs2_bbc_compressor_type jffs2_bbc_lzhd = { -+ "lzhd", -+ 0, -+ JFFS2_BBC_LZHD_BLOCK_SIGN, -+ jffs2_bbc_lzhd_compressor_init, -+ NULL, -+ NULL, -+ jffs2_bbc_lzhd_compressor_deinit, -+ jffs2_bbc_lzhd_compress, -+ jffs2_bbc_lzhd_estimate, -+ jffs2_bbc_lzhd_decompress, -+ jffs2_bbc_lzhd_proc_info, -+ jffs2_bbc_lzhd_proc_command -+}; -+ -+static int -+jffs2_bbc_lzhd_compressor_init (void) -+{ -+ return 0; -+} -+ -+static void -+jffs2_bbc_lzhd_compressor_deinit (void) -+{ -+} -+ -+static int -+jffs2_bbc_lzhd_compress (void *model, unsigned char *input, -+ unsigned char *output, unsigned long *sourcelen, -+ unsigned long *dstlen) -+{ -+ int retval; -+ unsigned long dst = *dstlen; -+ *(output++) = jffs2_bbc_lzhd.block_sign[0]; -+ *(output++) = jffs2_bbc_lzhd.block_sign[1]; -+ dst -= 2; -+ retval = Encode(input, output, sourcelen, &dst); -+ dst += 2; -+ *dstlen = dst; -+ return retval; -+} -+ -+static int -+jffs2_bbc_lzhd_estimate (void *model, unsigned char *input, -+ unsigned long sourcelen, unsigned long *dstlen, -+ unsigned long *readtime, unsigned long *writetime) -+{ -+ *dstlen = sourcelen * 55 / 100; -+ *readtime = JFFS2_BBC_ZLIB_READ_TIME * 8; -+ *writetime = JFFS2_BBC_ZLIB_WRITE_TIME * 65 / 10; -+ return 0; -+} -+ -+static int -+jffs2_bbc_lzhd_decompress (void *model, unsigned char *input, -+ unsigned char *output, unsigned long sourcelen, -+ unsigned long dstlen) -+{ -+ if ( ( *(input++) != (unsigned char)jffs2_bbc_lzhd.block_sign[0] ) || -+ ( *(input++) != (unsigned char)jffs2_bbc_lzhd.block_sign[1] ) -+ ) { -+ return -1; -+ } else { -+ return Decode(input, output, sourcelen - 2, dstlen); -+ } -+} -+ -+static char * -+jffs2_bbc_lzhd_proc_info (void) -+{ -+ return "Lempel-Ziv-(dynamic) Huffman compression module"; -+} -+ -+static int -+jffs2_bbc_lzhd_proc_command (char *command) -+{ -+ return 0; -+} -+ -+struct jffs2_bbc_compressor_type * -+jffs2_bbc_lzhd_init (int mode) -+{ -+ if (jffs2_bbc_register_compressor (&jffs2_bbc_lzhd) == 0) -+ { -+ return &jffs2_bbc_lzhd; -+ } -+ else -+ { -+ return NULL; -+ } -+} -+ -+void -+jffs2_bbc_lzhd_deinit (void) -+{ -+ jffs2_bbc_unregister_compressor (&jffs2_bbc_lzhd); -+} -diff -Nur linux-mips-cvs/fs/jffs2/jffs2_bbc_lzo_comp.c linux-mips/fs/jffs2/jffs2_bbc_lzo_comp.c ---- linux-mips-cvs/fs/jffs2/jffs2_bbc_lzo_comp.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-mips/fs/jffs2/jffs2_bbc_lzo_comp.c 2005-02-07 05:08:34.000000000 +0100 -@@ -0,0 +1,2435 @@ -+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */ -+ -+/* -+ jffs2_bbc_lzo_comp.c -- LZO1X-1 (and -999) compression module for jffs2 -+ Copyright (C) 2004 Patrik Kluba -+ Based on the original LZO sources -+ $Header: /openwrt/openwrt/package/linux/kernel-patches/301-jffs-compression,v 1.1 2005/03/26 10:33:31 wbx Exp $ -+*/ -+ -+/* -+ Original copyright notice follows: -+ -+ lzo1x_9x.c -- implementation of the LZO1X-999 compression algorithm -+ lzo_ptr.h -- low-level pointer constructs -+ lzo_swd.ch -- sliding window dictionary -+ lzoconf.h -- configuration for the LZO real-time data compression library -+ lzo_mchw.ch -- matching functions using a window -+ minilzo.c -- mini subset of the LZO real-time data compression library -+ config1x.h -- configuration for the LZO1X algorithm -+ lzo1x.h -- public interface of the LZO1X compression algorithm -+ -+ These files are part of the LZO real-time data compression library. -+ -+ Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer -+ All Rights Reserved. -+ -+ The LZO library is free software; you can redistribute it and/or -+ modify it under the terms of the GNU General Public License as -+ published by the Free Software Foundation; either version 2 of -+ the License, or (at your option) any later version. -+ -+ The LZO library is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ GNU General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with the LZO library; see the file COPYING. -+ If not, write to the Free Software Foundation, Inc., -+ 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -+ -+ Markus F.X.J. Oberhumer -+ <markus@oberhumer.com> -+*/ -+ -+/* -+ -+ 2004-02-16 pajko <pajko(AT)halom(DOT)u-szeged(DOT)hu> -+ Initial release -+ -removed all 16 bit code -+ -all sensitive data will be on 4 byte boundary -+ -removed check parts for library use -+ -removed all but LZO1X-* compression -+ -+*/ -+ -+#ifndef __KERNEL__ -+ #include <sys/types.h> -+ #include <stddef.h> -+ #include <string.h> -+ #include <limits.h> -+#else -+ #include <linux/kernel.h> -+ #include <linux/types.h> -+ #include <linux/stddef.h> -+ #include <linux/string.h> -+ #define USHRT_MAX 65535 -+ /* #define UINT_MAX 4294967295U */ -+#endif -+ -+/* data type definitions */ -+#define U32 unsigned long -+#define S32 signed long -+#define I32 long -+#define U16 unsigned short -+#define S16 signed short -+#define I16 short -+#define U8 unsigned char -+#define S8 signed char -+#define I8 char -+ -+/*************************************/ -+ -+/* lzo_swd.ch */ -+ -+#define SWD_N N -+#define SWD_F F -+#define SWD_THRESHOLD THRESHOLD -+ -+/* shortest unsigned int that 2 * SWD_F + SWD_N (currently 53248) fits in */ -+typedef unsigned short swd_uint; -+/* upper limit of that data type */ -+#define SWD_UINT_MAX USHRT_MAX -+ -+/* minilzo.c */ -+ -+#define LZO_VERSION_DATE "Jul 12 2002" -+#define LZO_VERSION_STRING "1.08" -+#define LZO_VERSION 0x1080 -+ -+/* lzo_ptr.h */ -+ -+/* Integral types that have *exactly* the same number of bits as a lzo_voidp */ -+typedef unsigned long lzo_ptr_t; -+typedef long lzo_sptr_t; -+ -+ -+/*************************************/ -+ -+/* config1x.h */ -+ -+#define M1_MAX_OFFSET 0x0400 -+#define M2_MAX_OFFSET 0x0800 -+#define M3_MAX_OFFSET 0x4000 -+#define M4_MAX_OFFSET 0xbfff -+ -+#define MX_MAX_OFFSET (M1_MAX_OFFSET + M2_MAX_OFFSET) -+ -+#define M1_MIN_LEN 2 -+#define M1_MAX_LEN 2 -+#define M2_MIN_LEN 3 -+#define M2_MAX_LEN 8 -+#define M3_MIN_LEN 3 -+#define M3_MAX_LEN 33 -+#define M4_MIN_LEN 3 -+#define M4_MAX_LEN 9 -+ -+#define M1_MARKER 0 -+#define M2_MARKER 64 -+#define M3_MARKER 32 -+#define M4_MARKER 16 -+ -+#define MIN_LOOKAHEAD (M2_MAX_LEN + 1) -+ -+/* minilzo.c */ -+ -+#define LZO_BYTE(x) ((unsigned char) ((x) & 0xff)) -+ -+#define LZO_MAX(a,b) ((a) >= (b) ? (a) : (b)) -+#define LZO_MIN(a,b) ((a) <= (b) ? (a) : (b)) -+#define LZO_MAX3(a,b,c) ((a) >= (b) ? LZO_MAX(a,c) : LZO_MAX(b,c)) -+#define LZO_MIN3(a,b,c) ((a) <= (b) ? LZO_MIN(a,c) : LZO_MIN(b,c)) -+ -+#define lzo_sizeof(type) ((lzo_uint) (sizeof(type))) -+ -+#define LZO_HIGH(array) ((lzo_uint) (sizeof(array)/sizeof(*(array)))) -+ -+#define LZO_SIZE(bits) (1u << (bits)) -+#define LZO_MASK(bits) (LZO_SIZE(bits) - 1) -+ -+#define LZO_LSIZE(bits) (1ul << (bits)) -+#define LZO_LMASK(bits) (LZO_LSIZE(bits) - 1) -+ -+#define LZO_USIZE(bits) ((lzo_uint) 1 << (bits)) -+#define LZO_UMASK(bits) (LZO_USIZE(bits) - 1) -+ -+#define LZO_STYPE_MAX(b) (((1l << (8*(b)-2)) - 1l) + (1l << (8*(b)-2))) -+#define LZO_UTYPE_MAX(b) (((1ul << (8*(b)-1)) - 1ul) + (1ul << (8*(b)-1))) -+ -+#define _LZO_STRINGIZE(x) #x -+#define _LZO_MEXPAND(x) _LZO_STRINGIZE(x) -+ -+#define _LZO_CONCAT2(a,b) a ## b -+#define _LZO_CONCAT3(a,b,c) a ## b ## c -+#define _LZO_CONCAT4(a,b,c,d) a ## b ## c ## d -+#define _LZO_CONCAT5(a,b,c,d,e) a ## b ## c ## d ## e -+ -+#define _LZO_ECONCAT2(a,b) _LZO_CONCAT2(a,b) -+#define _LZO_ECONCAT3(a,b,c) _LZO_CONCAT3(a,b,c) -+#define _LZO_ECONCAT4(a,b,c,d) _LZO_CONCAT4(a,b,c,d) -+#define _LZO_ECONCAT5(a,b,c,d,e) _LZO_CONCAT5(a,b,c,d,e) -+ -+#define lzo_dict_t const lzo_bytep -+#define lzo_dict_p lzo_dict_t * -+#define lzo_moff_t lzo_uint -+ -+#define MEMCPY8_DS(dest,src,len) \ -+ memcpy(dest,src,len); \ -+ dest += len; \ -+ src += len -+ -+#define MEMCPY_DS(dest,src,len) \ -+ do *dest++ = *src++; \ -+ while (--len > 0) -+ -+#define MEMMOVE_DS(dest,src,len) \ -+ do *dest++ = *src++; \ -+ while (--len > 0) -+ -+#define BZERO8_PTR(s,l,n) memset((s),0,(lzo_uint)(l)*(n)) -+ -+#define LZO_BASE 65521u -+#define LZO_NMAX 5552 -+ -+#define LZO_DO1(buf,i) {s1 += buf[i]; s2 += s1;} -+#define LZO_DO2(buf,i) LZO_DO1(buf,i); LZO_DO1(buf,i+1); -+#define LZO_DO4(buf,i) LZO_DO2(buf,i); LZO_DO2(buf,i+2); -+#define LZO_DO8(buf,i) LZO_DO4(buf,i); LZO_DO4(buf,i+4); -+#define LZO_DO16(buf,i) LZO_DO8(buf,i); LZO_DO8(buf,i+8); -+ -+#define IS_SIGNED(type) (((type) (-1)) < ((type) 0)) -+#define IS_UNSIGNED(type) (((type) (-1)) > ((type) 0)) -+ -+#define IS_POWER_OF_2(x) (((x) & ((x) - 1)) == 0) -+ -+#define D_BITS 14 -+#define D_INDEX1(d,p) d = DM((0x21*DX3(p,5,5,6)) >> 5) -+#define D_INDEX2(d,p) d = (d & (D_MASK & 0x7ff)) ^ (D_HIGH | 0x1f) -+ -+#define LZO_HASH LZO_HASH_LZO_INCREMENTAL_B -+ -+#define DL_MIN_LEN M2_MIN_LEN -+ -+#define D_SIZE LZO_SIZE(D_BITS) -+#define D_MASK LZO_MASK(D_BITS) -+ -+#define D_HIGH ((D_MASK >> 1) + 1) -+ -+#define DINDEX1 D_INDEX1 -+#define DINDEX2 D_INDEX2 -+ -+#define DX2(p,s1,s2) \ -+ (((((lzo_uint32)((p)[2]) << (s2)) ^ (p)[1]) << (s1)) ^ (p)[0]) -+ -+#define DX3(p,s1,s2,s3) ((DX2((p)+1,s2,s3) << (s1)) ^ (p)[0]) -+#define DMS(v,s) ((lzo_uint) (((v) & (D_MASK >> (s))) << (s))) -+#define DM(v) DMS(v,0) -+ -+#define DENTRY(p,in) (p) -+#define GINDEX(m_pos,m_off,dict,dindex,in) m_pos = dict[dindex] -+ -+#define LZO_CHECK_MPOS_DET(m_pos,m_off,in,ip,max_offset) \ -+ (m_pos == NULL || (m_off = (lzo_moff_t) (ip - m_pos)) > max_offset) -+ -+#define LZO_CHECK_MPOS_NON_DET(m_pos,m_off,in,ip,max_offset) \ -+ (BOUNDS_CHECKING_OFF_IN_EXPR( \ -+ (PTR_LT(m_pos,in) || \ -+ (m_off = (lzo_moff_t) PTR_DIFF(ip,m_pos)) <= 0 || \ -+ m_off > max_offset) )) -+ -+#define BOUNDS_CHECKING_OFF_IN_EXPR(expr) (expr) -+ -+#define DD_BITS 0 -+#define DD_SIZE LZO_SIZE(DD_BITS) -+#define DD_MASK LZO_MASK(DD_BITS) -+ -+#define DL_BITS (D_BITS - DD_BITS) -+#define DL_SIZE LZO_SIZE(DL_BITS) -+#define DL_MASK LZO_MASK(DL_BITS) -+ -+#define UPDATE_D(dict,drun,dv,p,in) dict[ DINDEX(dv,p) ] = DENTRY(p,in) -+#define UPDATE_I(dict,drun,index,p,in) dict[index] = DENTRY(p,in) -+#define UPDATE_P(ptr,drun,p,in) (ptr)[0] = DENTRY(p,in) -+ -+#define __COPY4(dst,src) * (lzo_uint32p)(dst) = * (const lzo_uint32p)(src) -+#define COPY4(dst,src) __COPY4((lzo_ptr_t)(dst),(lzo_ptr_t)(src)) -+ -+#define TEST_IP (ip < ip_end) -+#define TEST_OP (op <= op_end) -+ -+#define NEED_IP(x) \ -+ if ((lzo_uint)(ip_end - ip) < (lzo_uint)(x)) goto input_overrun -+#define NEED_OP(x) \ -+ if ((lzo_uint)(op_end - op) < (lzo_uint)(x)) goto output_overrun -+#define TEST_LOOKBEHIND(m_pos,out) if (m_pos < out) goto lookbehind_overrun -+ -+/* lzo1x_9x.c */ -+ -+#define LZO_UINT_MAX UINT_MAX -+#define N M4_MAX_OFFSET -+#define THRESHOLD 1 -+#define F 2048 -+ -+#define SWD_BEST_OFF (LZO_MAX3( M2_MAX_LEN, M3_MAX_LEN, M4_MAX_LEN ) + 1) -+ -+/* ../include/lzoconf.h */ -+ -+typedef U32 lzo_uint32; -+typedef I32 lzo_int32; -+typedef U32 lzo_uint; -+typedef I32 lzo_int; -+typedef int lzo_bool; -+ -+#define lzo_byte U8 -+#define lzo_bytep U8 * -+#define lzo_charp char * -+#define lzo_voidp void * -+#define lzo_shortp short * -+#define lzo_ushortp unsigned short * -+#define lzo_uint32p lzo_uint32 * -+#define lzo_int32p lzo_int32 * -+#define lzo_uintp lzo_uint * -+#define lzo_intp lzo_int * -+#define lzo_voidpp lzo_voidp * -+#define lzo_bytepp lzo_bytep * -+#define lzo_sizeof_dict_t sizeof(lzo_bytep) -+ -+#define LZO_E_OK 0 -+#define LZO_E_ERROR (-1) -+#define LZO_E_OUT_OF_MEMORY (-2) /* not used right now */ -+#define LZO_E_NOT_COMPRESSIBLE (-3) /* not used right now */ -+#define LZO_E_INPUT_OVERRUN (-4) -+#define LZO_E_OUTPUT_OVERRUN (-5) -+#define LZO_E_LOOKBEHIND_OVERRUN (-6) -+#define LZO_E_EOF_NOT_FOUND (-7) -+#define LZO_E_INPUT_NOT_CONSUMED (-8) -+ -+#define LZO_PTR_ALIGN_UP(_ptr,_size) \ -+ ((_ptr) + (lzo_uint) __lzo_align_gap((const lzo_voidp)(_ptr),(lzo_uint)(_size))) -+#define LZO_ALIGN(_ptr,_size) LZO_PTR_ALIGN_UP(_ptr,_size) -+ -+typedef int -+ (*lzo_compress_t) (const lzo_byte * src, lzo_uint src_len, -+ lzo_byte * dst, lzo_uintp dst_len, -+ lzo_voidp wrkmem); -+ -+typedef int -+ (*lzo_decompress_t) (const lzo_byte * src, lzo_uint src_len, -+ lzo_byte * dst, lzo_uintp dst_len, -+ lzo_voidp wrkmem); -+ -+typedef int -+ (*lzo_optimize_t) (lzo_byte * src, lzo_uint src_len, -+ lzo_byte * dst, lzo_uintp dst_len, -+ lzo_voidp wrkmem); -+ -+typedef int -+ (*lzo_compress_dict_t) (const lzo_byte * src, lzo_uint src_len, -+ lzo_byte * dst, lzo_uintp dst_len, -+ lzo_voidp wrkmem, -+ const lzo_byte * dict, lzo_uint dict_len); -+ -+typedef int -+ (*lzo_decompress_dict_t) (const lzo_byte * src, lzo_uint src_len, -+ lzo_byte * dst, lzo_uintp dst_len, -+ lzo_voidp wrkmem, -+ const lzo_byte * dict, lzo_uint dict_len); -+ -+typedef int -+ (*lzo_compress_asm_t) (const lzo_byte * src, lzo_uint src_len, -+ lzo_byte * dst, lzo_uintp dst_len, -+ lzo_voidp wrkmem); -+ -+typedef int -+ (*lzo_decompress_asm_t) (const lzo_byte * src, lzo_uint src_len, -+ lzo_byte * dst, lzo_uintp dst_len, -+ lzo_voidp wrkmem); -+ -+typedef void (*lzo_progress_callback_t) (lzo_uint, lzo_uint); -+ -+typedef union -+{ -+ lzo_bytep p; -+ lzo_uint u; -+} __lzo_pu_u; -+typedef union -+{ -+ lzo_bytep p; -+ lzo_uint32 u32; -+} __lzo_pu32_u; -+typedef union -+{ -+ void *vp; -+ lzo_bytep bp; -+ lzo_uint32 u32; -+ long l; -+} lzo_align_t; -+ -+/* lzo1x.h */ -+ -+#define LZO1X_1_MEM_COMPRESS ((lzo_uint32) (16384L * lzo_sizeof_dict_t)) -+#define LZO1X_999_MEM_COMPRESS ((lzo_uint32) (14 * 16384L * sizeof(short))) -+ -+/* lzo_ptr.h */ -+ -+#define PTR(a) ((lzo_ptr_t) (a)) -+#define PTR_LINEAR(a) PTR(a) -+#define PTR_ALIGNED_4(a) ((PTR_LINEAR(a) & 3) == 0) -+#define PTR_ALIGNED_8(a) ((PTR_LINEAR(a) & 7) == 0) -+#define PTR_ALIGNED2_4(a,b) (((PTR_LINEAR(a) | PTR_LINEAR(b)) & 3) == 0) -+#define PTR_ALIGNED2_8(a,b) (((PTR_LINEAR(a) | PTR_LINEAR(b)) & 7) == 0) -+#define PTR_LT(a,b) (PTR(a) < PTR(b)) -+#define PTR_GE(a,b) (PTR(a) >= PTR(b)) -+#define PTR_DIFF(a,b) ((lzo_ptrdiff_t) (PTR(a) - PTR(b))) -+#define pd(a,b) ((lzo_uint) ((a)-(b))) -+ -+typedef ptrdiff_t lzo_ptrdiff_t; -+ -+typedef union -+{ -+ char a_char; -+ unsigned char a_uchar; -+ short a_short; -+ unsigned short a_ushort; -+ int a_int; -+ unsigned int a_uint; -+ long a_long; -+ unsigned long a_ulong; -+ lzo_int a_lzo_int; -+ lzo_uint a_lzo_uint; -+ lzo_int32 a_lzo_int32; -+ lzo_uint32 a_lzo_uint32; -+ ptrdiff_t a_ptrdiff_t; -+ lzo_ptrdiff_t a_lzo_ptrdiff_t; -+ lzo_ptr_t a_lzo_ptr_t; -+ lzo_voidp a_lzo_voidp; -+ void *a_void_p; -+ lzo_bytep a_lzo_bytep; -+ lzo_bytepp a_lzo_bytepp; -+ lzo_uintp a_lzo_uintp; -+ lzo_uint *a_lzo_uint_p; -+ lzo_uint32p a_lzo_uint32p; -+ lzo_uint32 *a_lzo_uint32_p; -+ unsigned char *a_uchar_p; -+ char *a_char_p; -+} -+lzo_full_align_t; -+ -+/* lzo_mchw.ch */ -+ -+typedef struct -+{ -+ int init; -+ -+ lzo_uint look; -+ -+ lzo_uint m_len; -+ lzo_uint m_off; -+ -+ lzo_uint last_m_len; -+ lzo_uint last_m_off; -+ -+ const lzo_byte *bp; -+ const lzo_byte *ip; -+ const lzo_byte *in; -+ const lzo_byte *in_end; -+ lzo_byte *out; -+ -+ lzo_progress_callback_t cb; -+ -+ lzo_uint textsize; -+ lzo_uint codesize; -+ lzo_uint printcount; -+ -+ unsigned long lit_bytes; -+ unsigned long match_bytes; -+ unsigned long rep_bytes; -+ unsigned long lazy; -+ -+ lzo_uint r1_lit; -+ lzo_uint r1_m_len; -+ -+ unsigned long m1a_m, m1b_m, m2_m, m3_m, m4_m; -+ unsigned long lit1_r, lit2_r, lit3_r; -+} -+lzo1x_999_t; -+ -+#define getbyte(c) ((c).ip < (c).in_end ? *((c).ip)++ : (-1)) -+ -+/* lzo_swd.ch */ -+ -+#define SWD_UINT(x) ((swd_uint)(x)) -+#define SWD_HSIZE 16384 -+#define SWD_MAX_CHAIN 2048 -+#define HEAD3(b,p) \ -+ (((0x9f5f*(((((lzo_uint32)b[p]<<5)^b[p+1])<<5)^b[p+2]))>>5) & (SWD_HSIZE-1)) -+#define HEAD2(b,p) (b[p] ^ ((unsigned)b[p+1]<<8)) -+#define NIL2 SWD_UINT_MAX -+ -+typedef struct -+{ -+ lzo_uint n; -+ lzo_uint f; -+ lzo_uint threshold; -+ -+ lzo_uint max_chain; -+ lzo_uint nice_length; -+ lzo_bool use_best_off; -+ lzo_uint lazy_insert; -+ -+ lzo_uint m_len; -+ lzo_uint m_off; -+ lzo_uint look; -+ int b_char; -+ -+ lzo_uint best_off[SWD_BEST_OFF]; -+ -+ lzo1x_999_t *c; -+ lzo_uint m_pos; -+ -+ lzo_uint best_pos[SWD_BEST_OFF]; -+ -+ const lzo_byte *dict; -+ const lzo_byte *dict_end; -+ lzo_uint dict_len; -+ -+ lzo_uint ip; -+ lzo_uint bp; -+ lzo_uint rp; -+ lzo_uint b_size; -+ -+ unsigned char *b_wrap; -+ -+ lzo_uint node_count; -+ lzo_uint first_rp; -+ -+ unsigned char b[SWD_N + SWD_F + SWD_F]; -+ swd_uint head3[SWD_HSIZE]; -+ swd_uint succ3[SWD_N + SWD_F]; -+ swd_uint best3[SWD_N + SWD_F]; -+ swd_uint llen3[SWD_HSIZE]; -+ -+ swd_uint head2[65536L]; -+} -+lzo1x_999_swd_t; -+ -+#define s_head3(s,key) s->head3[key] -+#define swd_pos2off(s,pos) \ -+ (s->bp > (pos) ? s->bp - (pos) : s->b_size - ((pos) - s->bp)) -+ -+static __inline__ void -+swd_getbyte (lzo1x_999_swd_t * s) -+{ -+ int c; -+ -+ if ((c = getbyte (*(s->c))) < 0) -+ { -+ if (s->look > 0) -+ --s->look; -+ } -+ else -+ { -+ s->b[s->ip] = LZO_BYTE (c); -+ if (s->ip < s->f) -+ s->b_wrap[s->ip] = LZO_BYTE (c); -+ } -+ if (++s->ip == s->b_size) -+ s->ip = 0; -+ if (++s->bp == s->b_size) -+ s->bp = 0; -+ if (++s->rp == s->b_size) -+ s->rp = 0; -+} -+ -+static void -+swd_initdict (lzo1x_999_swd_t * s, const lzo_byte * dict, lzo_uint dict_len) -+{ -+ s->dict = s->dict_end = NULL; -+ s->dict_len = 0; -+ -+ if (!dict || dict_len <= 0) -+ return; -+ if (dict_len > s->n) -+ { -+ dict += dict_len - s->n; -+ dict_len = s->n; -+ } -+ -+ s->dict = dict; -+ s->dict_len = dict_len; -+ s->dict_end = dict + dict_len; -+ memcpy (s->b, dict, dict_len); -+ s->ip = dict_len; -+} -+ -+static void -+swd_insertdict (lzo1x_999_swd_t * s, lzo_uint node, lzo_uint len) -+{ -+ lzo_uint key; -+ -+ s->node_count = s->n - len; -+ s->first_rp = node; -+ -+ while (len-- > 0) -+ { -+ key = HEAD3 (s->b, node); -+ s->succ3[node] = s_head3 (s, key); -+ s->head3[key] = SWD_UINT (node); -+ s->best3[node] = SWD_UINT (s->f + 1); -+ s->llen3[key]++; -+ -+ key = HEAD2 (s->b, node); -+ s->head2[key] = SWD_UINT (node); -+ -+ node++; -+ } -+} -+ -+static int -+swd_init (lzo1x_999_swd_t * s, const lzo_byte * dict, lzo_uint dict_len) -+{ -+ -+ s->n = SWD_N; -+ s->f = SWD_F; -+ s->threshold = SWD_THRESHOLD; -+ -+ -+ -+ s->max_chain = SWD_MAX_CHAIN; -+ s->nice_length = SWD_F; -+ s->use_best_off = 0; -+ s->lazy_insert = 0; -+ -+ s->b_size = s->n + s->f; -+ if (2 * s->f >= s->n || s->b_size + s->f >= NIL2) -+ return LZO_E_ERROR; -+ s->b_wrap = s->b + s->b_size; -+ s->node_count = s->n; -+ -+ memset (s->llen3, 0, sizeof (s->llen3[0]) * SWD_HSIZE); -+ memset (s->head2, 0xff, sizeof (s->head2[0]) * 65536L); -+ -+ s->ip = 0; -+ swd_initdict (s, dict, dict_len); -+ s->bp = s->ip; -+ s->first_rp = s->ip; -+ -+ s->look = (lzo_uint) (s->c->in_end - s->c->ip); -+ if (s->look > 0) -+ { -+ if (s->look > s->f) -+ s->look = s->f; -+ memcpy (&s->b[s->ip], s->c->ip, s->look); -+ s->c->ip += s->look; -+ s->ip += s->look; -+ } -+ -+ if (s->ip == s->b_size) -+ s->ip = 0; -+ -+ if (s->look >= 2 && s->dict_len > 0) -+ swd_insertdict (s, 0, s->dict_len); -+ -+ s->rp = s->first_rp; -+ if (s->rp >= s->node_count) -+ s->rp -= s->node_count; -+ else -+ s->rp += s->b_size - s->node_count; -+ -+ return LZO_E_OK; -+} -+ -+static __inline__ void -+swd_remove_node (lzo1x_999_swd_t * s, lzo_uint node) -+{ -+ if (s->node_count == 0) -+ { -+ lzo_uint key; -+ -+ key = HEAD3 (s->b, node); -+ -+ --s->llen3[key]; -+ -+ key = HEAD2 (s->b, node); -+ -+ if ((lzo_uint) s->head2[key] == node) -+ s->head2[key] = NIL2; -+ } -+ else -+ --s->node_count; -+} -+ -+static void -+swd_accept (lzo1x_999_swd_t * s, lzo_uint n) -+{ -+ -+ while (n--) -+ { -+ lzo_uint key; -+ -+ swd_remove_node (s, s->rp); -+ -+ key = HEAD3 (s->b, s->bp); -+ s->succ3[s->bp] = s_head3 (s, key); -+ s->head3[key] = SWD_UINT (s->bp); -+ s->best3[s->bp] = SWD_UINT (s->f + 1); -+ s->llen3[key]++; -+ -+ key = HEAD2 (s->b, s->bp); -+ s->head2[key] = SWD_UINT (s->bp);; -+ -+ swd_getbyte (s); -+ } -+} -+ -+static void -+swd_search (lzo1x_999_swd_t * s, lzo_uint node, lzo_uint cnt) -+{ -+ const unsigned char *p1; -+ const unsigned char *p2; -+ const unsigned char *px; -+ -+ lzo_uint m_len = s->m_len; -+ const unsigned char *b = s->b; -+ const unsigned char *bp = s->b + s->bp; -+ const unsigned char *bx = s->b + s->bp + s->look; -+ unsigned char scan_end1; -+ -+ scan_end1 = bp[m_len - 1]; -+ for (; cnt-- > 0; node = s->succ3[node]) -+ { -+ p1 = bp; -+ p2 = b + node; -+ px = bx; -+ -+ if (p2[m_len - 1] == scan_end1 && -+ p2[m_len] == p1[m_len] && -+ p2[0] == p1[0] && p2[1] == p1[1]) -+ { -+ lzo_uint i; -+ -+ p1 += 2; -+ p2 += 2; -+ do -+ { -+ } -+ while (++p1 < px && *p1 == *++p2); -+ -+ i = p1 - bp; -+ -+ if (i < SWD_BEST_OFF) -+ { -+ if (s->best_pos[i] == 0) -+ s->best_pos[i] = node + 1; -+ } -+ -+ if (i > m_len) -+ { -+ s->m_len = m_len = i; -+ s->m_pos = node; -+ if (m_len == s->look) -+ return; -+ if (m_len >= s->nice_length) -+ return; -+ if (m_len > (lzo_uint) s->best3[node]) -+ return; -+ scan_end1 = bp[m_len - 1]; -+ } -+ } -+ } -+} -+ -+static lzo_bool -+swd_search2 (lzo1x_999_swd_t * s) -+{ -+ lzo_uint key; -+ -+ key = s->head2[HEAD2 (s->b, s->bp)]; -+ if (key == NIL2) -+ return 0; -+ -+ if (s->best_pos[2] == 0) -+ s->best_pos[2] = key + 1; -+ -+ if (s->m_len < 2) -+ { -+ s->m_len = 2; -+ s->m_pos = key; -+ } -+ return 1; -+} -+ -+static void -+swd_findbest (lzo1x_999_swd_t * s) -+{ -+ lzo_uint key; -+ lzo_uint cnt, node; -+ lzo_uint len; -+ -+ key = HEAD3 (s->b, s->bp); -+ node = s->succ3[s->bp] = s_head3 (s, key); -+ cnt = s->llen3[key]++; -+ -+ if (cnt > s->max_chain && s->max_chain > 0) -+ cnt = s->max_chain; -+ s->head3[key] = SWD_UINT (s->bp); -+ -+ s->b_char = s->b[s->bp]; -+ len = s->m_len; -+ if (s->m_len >= s->look) -+ { -+ if (s->look == 0) -+ s->b_char = -1; -+ s->m_off = 0; -+ s->best3[s->bp] = SWD_UINT (s->f + 1); -+ } -+ else -+ { -+ -+ if (swd_search2 (s)) -+ -+ if (s->look >= 3) -+ swd_search (s, node, cnt); -+ if (s->m_len > len) -+ s->m_off = swd_pos2off (s, s->m_pos); -+ s->best3[s->bp] = SWD_UINT (s->m_len); -+ -+ if (s->use_best_off) -+ { -+ int i; -+ for (i = 2; i < SWD_BEST_OFF; i++) -+ if (s->best_pos[i] > 0) -+ s->best_off[i] = -+ swd_pos2off (s, -+ s->best_pos[i] - -+ 1); -+ else -+ s->best_off[i] = 0; -+ } -+ -+ } -+ -+ swd_remove_node (s, s->rp); -+ -+ key = HEAD2 (s->b, s->bp); -+ s->head2[key] = SWD_UINT (s->bp); -+ -+} -+ -+/* lzo_mchw.ch */ -+ -+static int -+init_match (lzo1x_999_t * c, lzo1x_999_swd_t * s, -+ const lzo_byte * dict, lzo_uint dict_len, lzo_uint32 flags) -+{ -+ int r; -+ -+ c->init = 1; -+ -+ s->c = c; -+ -+ c->last_m_len = c->last_m_off = 0; -+ -+ c->textsize = c->codesize = c->printcount = 0; -+ c->lit_bytes = c->match_bytes = c->rep_bytes = 0; -+ c->lazy = 0; -+ -+ r = swd_init (s, dict, dict_len); -+ if (r != 0) -+ return r; -+ -+ s->use_best_off = (flags & 1) ? 1 : 0; -+ return r; -+} -+ -+static int -+find_match (lzo1x_999_t * c, lzo1x_999_swd_t * s, -+ lzo_uint this_len, lzo_uint skip) -+{ -+ if (skip > 0) -+ { -+ swd_accept (s, this_len - skip); -+ c->textsize += this_len - skip + 1; -+ } -+ else -+ { -+ c->textsize += this_len - skip; -+ } -+ -+ s->m_len = 1; -+ s->m_len = 1; -+ -+ if (s->use_best_off) -+ memset (s->best_pos, 0, sizeof (s->best_pos)); -+ -+ swd_findbest (s); -+ c->m_len = s->m_len; -+ c->m_off = s->m_off; -+ -+ swd_getbyte (s); -+ -+ if (s->b_char < 0) -+ { -+ c->look = 0; -+ c->m_len = 0; -+ } -+ else -+ { -+ c->look = s->look + 1; -+ } -+ c->bp = c->ip - c->look; -+ -+ if (c->cb && c->textsize > c->printcount) -+ { -+ (*c->cb) (c->textsize, c->codesize); -+ c->printcount += 1024; -+ } -+ -+ return LZO_E_OK; -+} -+ -+/* lzo1x_9x.c */ -+ -+static lzo_byte * -+code_match (lzo1x_999_t * c, lzo_byte * op, lzo_uint m_len, lzo_uint m_off) -+{ -+ lzo_uint x_len = m_len; -+ lzo_uint x_off = m_off; -+ -+ c->match_bytes += m_len; -+ -+ if (m_len == 2) -+ { -+ m_off -= 1; -+ -+ *op++ = LZO_BYTE (M1_MARKER | ((m_off & 3) << 2)); -+ *op++ = LZO_BYTE (m_off >> 2); -+ -+ c->m1a_m++; -+ } -+ -+ else if (m_len <= M2_MAX_LEN && m_off <= M2_MAX_OFFSET) -+ -+ { -+ -+ m_off -= 1; -+ *op++ = LZO_BYTE (((m_len - 1) << 5) | ((m_off & 7) << 2)); -+ *op++ = LZO_BYTE (m_off >> 3); -+ c->m2_m++; -+ } -+ else if (m_len == M2_MIN_LEN && m_off <= MX_MAX_OFFSET -+ && c->r1_lit >= 4) -+ { -+ m_off -= 1 + M2_MAX_OFFSET; -+ -+ *op++ = LZO_BYTE (M1_MARKER | ((m_off & 3) << 2)); -+ *op++ = LZO_BYTE (m_off >> 2); -+ -+ c->m1b_m++; -+ } -+ else if (m_off <= M3_MAX_OFFSET) -+ { -+ m_off -= 1; -+ if (m_len <= M3_MAX_LEN) -+ *op++ = LZO_BYTE (M3_MARKER | (m_len - 2)); -+ else -+ { -+ m_len -= M3_MAX_LEN; -+ *op++ = M3_MARKER | 0; -+ while (m_len > 255) -+ { -+ m_len -= 255; -+ *op++ = 0; -+ } -+ *op++ = LZO_BYTE (m_len); -+ } -+ -+ *op++ = LZO_BYTE (m_off << 2); -+ *op++ = LZO_BYTE (m_off >> 6); -+ -+ c->m3_m++; -+ } -+ else -+ { -+ lzo_uint k; -+ -+ m_off -= 0x4000; -+ k = (m_off & 0x4000) >> 11; -+ if (m_len <= M4_MAX_LEN) -+ *op++ = LZO_BYTE (M4_MARKER | k | (m_len - 2)); -+ else -+ { -+ m_len -= M4_MAX_LEN; -+ *op++ = LZO_BYTE (M4_MARKER | k | 0); -+ while (m_len > 255) -+ { -+ m_len -= 255; -+ *op++ = 0; -+ } -+ *op++ = LZO_BYTE (m_len); -+ } -+ -+ *op++ = LZO_BYTE (m_off << 2); -+ *op++ = LZO_BYTE (m_off >> 6); -+ -+ c->m4_m++; -+ } -+ -+ c->last_m_len = x_len; -+ c->last_m_off = x_off; -+ return op; -+} -+ -+static lzo_byte * -+STORE_RUN (lzo1x_999_t * c, lzo_byte * op, const lzo_byte * ii, lzo_uint t) -+{ -+ c->lit_bytes += t; -+ -+ if (op == c->out && t <= 238) -+ { -+ *op++ = LZO_BYTE (17 + t); -+ } -+ else if (t <= 3) -+ { -+ op[-2] |= LZO_BYTE (t); -+ -+ c->lit1_r++; -+ } -+ else if (t <= 18) -+ { -+ *op++ = LZO_BYTE (t - 3); -+ c->lit2_r++; -+ } -+ else -+ { -+ lzo_uint tt = t - 18; -+ -+ *op++ = 0; -+ while (tt > 255) -+ { -+ tt -= 255; -+ *op++ = 0; -+ } -+ *op++ = LZO_BYTE (tt); -+ c->lit3_r++; -+ } -+ do -+ *op++ = *ii++; -+ while (--t > 0); -+ -+ return op; -+} -+ -+static lzo_byte * -+code_run (lzo1x_999_t * c, lzo_byte * op, const lzo_byte * ii, -+ lzo_uint lit, lzo_uint m_len) -+{ -+ if (lit > 0) -+ { -+ op = STORE_RUN (c, op, ii, lit); -+ c->r1_m_len = m_len; -+ c->r1_lit = lit; -+ } -+ else -+ { -+ c->r1_m_len = 0; -+ c->r1_lit = 0; -+ } -+ -+ return op; -+} -+ -+static int -+len_of_coded_match (lzo_uint m_len, lzo_uint m_off, lzo_uint lit) -+{ -+ int n = 4; -+ -+ if (m_len < 2) -+ return -1; -+ if (m_len == 2) -+ return (m_off <= M1_MAX_OFFSET && lit > 0 -+ && lit < 4) ? 2 : -1; -+ if (m_len <= M2_MAX_LEN && m_off <= M2_MAX_OFFSET) -+ return 2; -+ if (m_len == M2_MIN_LEN && m_off <= MX_MAX_OFFSET && lit >= 4) -+ return 2; -+ if (m_off <= M3_MAX_OFFSET) -+ { -+ if (m_len <= M3_MAX_LEN) -+ return 3; -+ m_len -= M3_MAX_LEN; -+ while (m_len > 255) -+ { -+ m_len -= 255; -+ n++; -+ } -+ return n; -+ } -+ if (m_off <= M4_MAX_OFFSET) -+ { -+ if (m_len <= M4_MAX_LEN) -+ return 3; -+ m_len -= M4_MAX_LEN; -+ while (m_len > 255) -+ { -+ m_len -= 255; -+ n++; -+ } -+ return n; -+ } -+ return -1; -+} -+ -+static lzo_int -+min_gain (lzo_uint ahead, lzo_uint lit1, lzo_uint lit2, int l1, int l2, -+ int l3) -+{ -+ lzo_int lazy_match_min_gain = 0; -+ -+ lazy_match_min_gain += ahead; -+ -+ if (lit1 <= 3) -+ lazy_match_min_gain += (lit2 <= 3) ? 0 : 2; -+ else if (lit1 <= 18) -+ lazy_match_min_gain += (lit2 <= 18) ? 0 : 1; -+ -+ lazy_match_min_gain += (l2 - l1) * 2; -+ if (l3 > 0) -+ lazy_match_min_gain -= (ahead - l3) * 2; -+ -+ if (lazy_match_min_gain < 0) -+ lazy_match_min_gain = 0; -+ -+ return lazy_match_min_gain; -+} -+ -+static void -+better_match (const lzo1x_999_swd_t * swd, lzo_uint * m_len, lzo_uint * m_off) -+{ -+ if (*m_len <= M2_MIN_LEN) -+ return; -+ -+ if (*m_off <= M2_MAX_OFFSET) -+ return; -+ -+ if (*m_off > M2_MAX_OFFSET && -+ *m_len >= M2_MIN_LEN + 1 && *m_len <= M2_MAX_LEN + 1 && -+ swd->best_off[*m_len - 1] -+ && swd->best_off[*m_len - 1] <= M2_MAX_OFFSET) -+ { -+ *m_len = *m_len - 1; -+ *m_off = swd->best_off[*m_len]; -+ return; -+ } -+ -+ if (*m_off > M3_MAX_OFFSET && -+ *m_len >= M4_MAX_LEN + 1 && *m_len <= M2_MAX_LEN + 2 && -+ swd->best_off[*m_len - 2] -+ && swd->best_off[*m_len - 2] <= M2_MAX_OFFSET) -+ { -+ *m_len = *m_len - 2; -+ *m_off = swd->best_off[*m_len]; -+ return; -+ } -+ -+ if (*m_off > M3_MAX_OFFSET && -+ *m_len >= M4_MAX_LEN + 1 && *m_len <= M3_MAX_LEN + 1 && -+ swd->best_off[*m_len - 1] -+ && swd->best_off[*m_len - 1] <= M3_MAX_OFFSET) -+ { -+ *m_len = *m_len - 1; -+ *m_off = swd->best_off[*m_len]; -+ } -+ -+} -+ -+/* minilzo.c */ -+ -+static lzo_bool -+lzo_assert (int expr) -+{ -+ return (expr) ? 1 : 0; -+} -+ -+/* lzo1x_9x.c */ -+ -+static int -+lzo1x_999_compress_internal (const lzo_byte * in, lzo_uint in_len, -+ lzo_byte * out, lzo_uintp out_len, -+ lzo_voidp wrkmem, -+ const lzo_byte * dict, lzo_uint dict_len, -+ lzo_progress_callback_t cb, -+ int try_lazy, -+ lzo_uint good_length, -+ lzo_uint max_lazy, -+ lzo_uint nice_length, -+ lzo_uint max_chain, lzo_uint32 flags) -+{ -+ lzo_byte *op; -+ const lzo_byte *ii; -+ lzo_uint lit; -+ lzo_uint m_len, m_off; -+ lzo1x_999_t cc; -+ lzo1x_999_t *const c = &cc; -+ lzo1x_999_swd_t *const swd = (lzo1x_999_swd_t *) wrkmem; -+ int r; -+ -+ if (!lzo_assert -+ (LZO1X_999_MEM_COMPRESS >= lzo_sizeof (lzo1x_999_swd_t))) -+ return LZO_E_ERROR; -+ -+ if (try_lazy < 0) -+ try_lazy = 1; -+ -+ if (good_length <= 0) -+ good_length = 32; -+ -+ if (max_lazy <= 0) -+ max_lazy = 32; -+ -+ if (nice_length <= 0) -+ nice_length = 0; -+ -+ if (max_chain <= 0) -+ max_chain = SWD_MAX_CHAIN; -+ -+ c->init = 0; -+ c->ip = c->in = in; -+ c->in_end = in + in_len; -+ c->out = out; -+ c->cb = cb; -+ c->m1a_m = c->m1b_m = c->m2_m = c->m3_m = c->m4_m = 0; -+ c->lit1_r = c->lit2_r = c->lit3_r = 0; -+ -+ op = out; -+ ii = c->ip; -+ lit = 0; -+ c->r1_lit = c->r1_m_len = 0; -+ -+ r = init_match (c, swd, dict, dict_len, flags); -+ if (r != 0) -+ return r; -+ if (max_chain > 0) -+ swd->max_chain = max_chain; -+ if (nice_length > 0) -+ swd->nice_length = nice_length; -+ -+ r = find_match (c, swd, 0, 0); -+ if (r != 0) -+ return r; -+ while (c->look > 0) -+ { -+ lzo_uint ahead; -+ lzo_uint max_ahead; -+ int l1, l2, l3; -+ -+ c->codesize = op - out; -+ -+ m_len = c->m_len; -+ m_off = c->m_off; -+ -+ if (lit == 0) -+ ii = c->bp; -+ -+ if (m_len < 2 || -+ (m_len == 2 -+ && (m_off > M1_MAX_OFFSET || lit == 0 || lit >= 4)) -+ || (m_len == 2 && op == out) || (op == out && lit == 0)) -+ { -+ -+ m_len = 0; -+ } -+ else if (m_len == M2_MIN_LEN) -+ { -+ -+ if (m_off > MX_MAX_OFFSET && lit >= 4) -+ m_len = 0; -+ } -+ -+ if (m_len == 0) -+ { -+ -+ lit++; -+ swd->max_chain = max_chain; -+ r = find_match (c, swd, 1, 0); -+ continue; -+ } -+ -+ if (swd->use_best_off) -+ better_match (swd, &m_len, &m_off); -+ -+ ahead = 0; -+ if (try_lazy <= 0 || m_len >= max_lazy) -+ { -+ -+ l1 = 0; -+ max_ahead = 0; -+ } -+ else -+ { -+ -+ l1 = len_of_coded_match (m_len, m_off, lit); -+ -+ max_ahead = LZO_MIN (try_lazy, l1 - 1); -+ -+ } -+ -+ while (ahead < max_ahead && c->look > m_len) -+ { -+ lzo_int lazy_match_min_gain; -+ -+ if (m_len >= good_length) -+ swd->max_chain = max_chain >> 2; -+ else -+ swd->max_chain = max_chain; -+ r = find_match (c, swd, 1, 0); -+ ahead++; -+ -+ if (c->m_len < m_len) -+ continue; -+ -+ if (c->m_len == m_len && c->m_off >= m_off) -+ continue; -+ -+ if (swd->use_best_off) -+ better_match (swd, &c->m_len, &c->m_off); -+ -+ l2 = len_of_coded_match (c->m_len, c->m_off, -+ lit + ahead); -+ if (l2 < 0) -+ continue; -+ -+ l3 = (op == out) ? -1 : len_of_coded_match (ahead, -+ m_off, -+ lit); -+ -+ lazy_match_min_gain = -+ min_gain (ahead, lit, lit + ahead, l1, l2, -+ l3); -+ if (c->m_len >= m_len + lazy_match_min_gain) -+ { -+ c->lazy++; -+ -+ if (l3 > 0) -+ { -+ -+ op = code_run (c, op, ii, lit, ahead); -+ lit = 0; -+ -+ op = code_match (c, op, ahead, m_off); -+ } -+ else -+ { -+ lit += ahead; -+ } -+ goto lazy_match_done; -+ } -+ } -+ -+ op = code_run (c, op, ii, lit, m_len); -+ lit = 0; -+ -+ op = code_match (c, op, m_len, m_off); -+ swd->max_chain = max_chain; -+ r = find_match (c, swd, m_len, 1 + ahead); -+ -+ lazy_match_done:; -+ } -+ -+ if (lit > 0) -+ op = STORE_RUN (c, op, ii, lit); -+ -+ *op++ = M4_MARKER | 1; -+ *op++ = 0; -+ *op++ = 0; -+ -+ c->codesize = op - out; -+ -+ *out_len = op - out; -+ -+ if (c->cb) -+ (*c->cb) (c->textsize, c->codesize); -+ -+ return LZO_E_OK; -+} -+ -+static int -+lzo1x_999_compress_level (const lzo_byte * in, lzo_uint in_len, -+ lzo_byte * out, lzo_uintp out_len, -+ lzo_voidp wrkmem, -+ const lzo_byte * dict, lzo_uint dict_len, -+ lzo_progress_callback_t cb, int compression_level) -+{ -+ static const struct -+ { -+ int try_lazy; -+ lzo_uint good_length; -+ lzo_uint max_lazy; -+ lzo_uint nice_length; -+ lzo_uint max_chain; -+ lzo_uint32 flags; -+ } c[9] = -+ { -+ { -+ 0, 0, 0, 8, 4, 0}, -+ { -+ 0, 0, 0, 16, 8, 0}, -+ { -+ 0, 0, 0, 32, 16, 0}, -+ { -+ 1, 4, 4, 16, 16, 0}, -+ { -+ 1, 8, 16, 32, 32, 0}, -+ { -+ 1, 8, 16, 128, 128, 0}, -+ { -+ 2, 8, 32, 128, 256, 0}, -+ { -+ 2, 32, 128, F, 2048, 1}, -+ { -+ 2, F, F, F, 4096, 1} -+ }; -+ -+ if (compression_level < 1 || compression_level > 9) -+ return LZO_E_ERROR; -+ -+ compression_level -= 1; -+ return lzo1x_999_compress_internal (in, in_len, out, out_len, wrkmem, -+ dict, dict_len, cb, -+ c[compression_level].try_lazy, -+ c[compression_level].good_length, -+ c[compression_level].max_lazy, -+ 0, -+ c[compression_level].max_chain, -+ c[compression_level].flags); -+} -+ -+static int -+lzo1x_999_compress (const lzo_byte * in, lzo_uint in_len, -+ lzo_byte * out, lzo_uintp out_len, lzo_voidp wrkmem) -+{ -+ return lzo1x_999_compress_level (in, in_len, out, out_len, wrkmem, -+ NULL, 0, 0, 8); -+} -+ -+/* minilzo.c */ -+ -+static const lzo_byte __lzo_copyright[] = LZO_VERSION_STRING; -+ -+static lzo_uint -+_lzo1x_1_do_compress (const lzo_byte * in, lzo_uint in_len, -+ lzo_byte * out, lzo_uintp out_len, lzo_voidp wrkmem) -+{ -+ -+ register const lzo_byte *ip; -+ -+ lzo_byte *op; -+ const lzo_byte *const in_end = in + in_len; -+ const lzo_byte *const ip_end = in + in_len - 8 - 5; -+ const lzo_byte *ii; -+ lzo_dict_p const dict = (lzo_dict_p) wrkmem; -+ -+ op = out; -+ ip = in; -+ ii = ip; -+ -+ ip += 4; -+ for (;;) -+ { -+ register const lzo_byte *m_pos; -+ -+ lzo_uint m_off; -+ lzo_uint m_len; -+ lzo_uint dindex; -+ -+ DINDEX1 (dindex, ip); -+ GINDEX (m_pos, m_off, dict, dindex, in); -+ if (LZO_CHECK_MPOS_NON_DET -+ (m_pos, m_off, in, ip, M4_MAX_OFFSET)) -+ goto literal; -+ -+ if (m_off <= M2_MAX_OFFSET || m_pos[3] == ip[3]) -+ goto try_match; -+ DINDEX2 (dindex, ip); -+ GINDEX (m_pos, m_off, dict, dindex, in); -+ -+ if (LZO_CHECK_MPOS_NON_DET -+ (m_pos, m_off, in, ip, M4_MAX_OFFSET)) -+ goto literal; -+ if (m_off <= M2_MAX_OFFSET || m_pos[3] == ip[3]) -+ goto try_match; -+ goto literal; -+ -+ try_match: -+ if (m_pos[0] != ip[0] || m_pos[1] != ip[1]) -+ { -+ } -+ else -+ { -+ if (m_pos[2] == ip[2]) -+ { -+ goto match; -+ } -+ else -+ { -+ } -+ } -+ -+ literal: -+ UPDATE_I (dict, 0, dindex, ip, in); -+ ++ip; -+ if (ip >= ip_end) -+ break; -+ continue; -+ -+ match: -+ UPDATE_I (dict, 0, dindex, ip, in); -+ -+ if (pd (ip, ii) > 0) -+ { -+ register lzo_uint t = pd (ip, ii); -+ -+ if (t <= 3) -+ { -+ op[-2] |= LZO_BYTE (t); -+ } -+ else if (t <= 18) -+ *op++ = LZO_BYTE (t - 3); -+ else -+ { -+ register lzo_uint tt = t - 18; -+ -+ *op++ = 0; -+ while (tt > 255) -+ { -+ tt -= 255; -+ *op++ = 0; -+ } -+ *op++ = LZO_BYTE (tt);; -+ } -+ do -+ *op++ = *ii++; -+ while (--t > 0); -+ } -+ -+ ip += 3; -+ if (m_pos[3] != *ip++ || m_pos[4] != *ip++ -+ || m_pos[5] != *ip++ || m_pos[6] != *ip++ -+ || m_pos[7] != *ip++ || m_pos[8] != *ip++) -+ { -+ --ip; -+ m_len = ip - ii; -+ -+ if (m_off <= M2_MAX_OFFSET) -+ { -+ m_off -= 1; -+ -+ *op++ = LZO_BYTE (((m_len - -+ 1) << 5) | ((m_off & 7) << -+ 2)); -+ *op++ = LZO_BYTE (m_off >> 3); -+ } -+ else if (m_off <= M3_MAX_OFFSET) -+ { -+ m_off -= 1; -+ *op++ = LZO_BYTE (M3_MARKER | (m_len - 2)); -+ goto m3_m4_offset; -+ } -+ else -+ -+ { -+ m_off -= 0x4000; -+ -+ *op++ = LZO_BYTE (M4_MARKER | -+ ((m_off & 0x4000) >> 11) | -+ (m_len - 2)); -+ goto m3_m4_offset; -+ } -+ } -+ else -+ { -+ { -+ const lzo_byte *end = in_end; -+ const lzo_byte *m = m_pos + M2_MAX_LEN + 1; -+ while (ip < end && *m == *ip) -+ m++, ip++; -+ m_len = (ip - ii); -+ } -+ -+ -+ if (m_off <= M3_MAX_OFFSET) -+ { -+ m_off -= 1; -+ if (m_len <= 33) -+ *op++ = LZO_BYTE (M3_MARKER | -+ (m_len - 2)); -+ else -+ { -+ m_len -= 33; -+ *op++ = M3_MARKER | 0; -+ goto m3_m4_len; -+ } -+ } -+ else -+ { -+ m_off -= 0x4000; -+ -+ if (m_len <= M4_MAX_LEN) -+ *op++ = LZO_BYTE (M4_MARKER | -+ ((m_off & 0x4000) >> -+ 11) | (m_len - 2)); -+ -+ else -+ { -+ m_len -= M4_MAX_LEN; -+ *op++ = LZO_BYTE (M4_MARKER | -+ ((m_off & 0x4000) >> -+ 11)); -+ m3_m4_len: -+ while (m_len > 255) -+ { -+ m_len -= 255; -+ *op++ = 0; -+ } -+ -+ *op++ = LZO_BYTE (m_len); -+ } -+ } -+ -+ m3_m4_offset: -+ *op++ = LZO_BYTE ((m_off & 63) << 2); -+ *op++ = LZO_BYTE (m_off >> 6); -+ } -+ ii = ip; -+ if (ip >= ip_end) -+ break; -+ } -+ -+ *out_len = op - out; -+ return pd (in_end, ii); -+} -+ -+static int -+lzo1x_1_compress (const lzo_byte * in, lzo_uint in_len, -+ lzo_byte * out, lzo_uintp out_len, lzo_voidp wrkmem) -+{ -+ lzo_byte *op = out; -+ lzo_uint t; -+ -+ if (in_len <= M2_MAX_LEN + 5) -+ t = in_len; -+ else -+ { -+ t = _lzo1x_1_do_compress (in, in_len, op, out_len, wrkmem); -+ op += *out_len; -+ } -+ -+ if (t > 0) -+ { -+ const lzo_byte *ii = in + in_len - t; -+ -+ if (op == out && t <= 238) -+ *op++ = LZO_BYTE (17 + t); -+ else if (t <= 3) -+ op[-2] |= LZO_BYTE (t); -+ else if (t <= 18) -+ *op++ = LZO_BYTE (t - 3); -+ else -+ { -+ lzo_uint tt = t - 18; -+ -+ *op++ = 0; -+ while (tt > 255) -+ { -+ tt -= 255; -+ *op++ = 0; -+ } -+ -+ *op++ = LZO_BYTE (tt); -+ } -+ do -+ *op++ = *ii++; -+ while (--t > 0); -+ } -+ -+ *op++ = M4_MARKER | 1; -+ *op++ = 0; -+ *op++ = 0; -+ -+ *out_len = op - out; -+ return 0; -+} -+ -+static int -+lzo1x_decompress (const lzo_byte * in, lzo_uint in_len, -+ lzo_byte * out, lzo_uintp out_len, lzo_voidp wrkmem) -+{ -+ register lzo_byte *op; -+ register const lzo_byte *ip; -+ register lzo_uint t; -+ -+ register const lzo_byte *m_pos; -+ -+ const lzo_byte *const ip_end = in + in_len; -+ lzo_byte *const op_end = out + *out_len; -+ -+ *out_len = 0; -+ -+ op = out; -+ ip = in; -+ -+ if (*ip > 17) -+ { -+ t = *ip++ - 17; -+ if (t < 4) -+ goto match_next; -+ NEED_OP (t); -+ NEED_IP (t + 1); -+ do -+ *op++ = *ip++; -+ while (--t > 0); -+ goto first_literal_run; -+ } -+ -+ while (TEST_IP && TEST_OP) -+ { -+ t = *ip++; -+ if (t >= 16) -+ goto match; -+ if (t == 0) -+ { -+ NEED_IP (1); -+ while (*ip == 0) -+ { -+ t += 255; -+ ip++; -+ NEED_IP (1); -+ } -+ t += 15 + *ip++; -+ } -+ NEED_OP (t + 3); -+ NEED_IP (t + 4); -+ if (PTR_ALIGNED2_4 (op, ip)) -+ { -+ COPY4 (op, ip); -+ -+ op += 4; -+ ip += 4; -+ if (--t > 0) -+ { -+ if (t >= 4) -+ { -+ do -+ { -+ COPY4 (op, ip); -+ op += 4; -+ ip += 4; -+ t -= 4; -+ } -+ while (t >= 4); -+ if (t > 0) -+ do -+ *op++ = *ip++; -+ while (--t > 0); -+ } -+ else -+ do -+ *op++ = *ip++; -+ while (--t > 0); -+ } -+ } -+ else -+ { -+ *op++ = *ip++; -+ *op++ = *ip++; -+ *op++ = *ip++; -+ do -+ *op++ = *ip++; -+ while (--t > 0); -+ } -+ first_literal_run: -+ -+ t = *ip++; -+ if (t >= 16) -+ goto match; -+ -+ m_pos = op - (1 + M2_MAX_OFFSET); -+ m_pos -= t >> 2; -+ m_pos -= *ip++ << 2; -+ TEST_LOOKBEHIND (m_pos, out); -+ NEED_OP (3); -+ *op++ = *m_pos++; -+ *op++ = *m_pos++; -+ *op++ = *m_pos; -+ -+ goto match_done; -+ -+ while (TEST_IP && TEST_OP) -+ { -+ match: -+ if (t >= 64) -+ { -+ m_pos = op - 1; -+ m_pos -= (t >> 2) & 7; -+ m_pos -= *ip++ << 3; -+ t = (t >> 5) - 1; -+ TEST_LOOKBEHIND (m_pos, out); -+ NEED_OP (t + 3 - 1); -+ goto copy_match; -+ -+ } -+ else if (t >= 32) -+ { -+ t &= 31; -+ if (t == 0) -+ { -+ NEED_IP (1); -+ while (*ip == 0) -+ { -+ t += 255; -+ ip++; -+ NEED_IP (1); -+ } -+ t += 31 + *ip++; -+ } -+ -+ m_pos = op - 1; -+ m_pos -= (ip[0] >> 2) + (ip[1] << 6); -+ -+ ip += 2; -+ } -+ else if (t >= 16) -+ { -+ m_pos = op; -+ m_pos -= (t & 8) << 11; -+ -+ t &= 7; -+ if (t == 0) -+ { -+ NEED_IP (1); -+ while (*ip == 0) -+ { -+ t += 255; -+ ip++; -+ NEED_IP (1); -+ } -+ t += 7 + *ip++; -+ } -+ -+ m_pos -= (ip[0] >> 2) + (ip[1] << 6); -+ -+ ip += 2; -+ if (m_pos == op) -+ goto eof_found; -+ m_pos -= 0x4000; -+ } -+ else -+ { -+ -+ m_pos = op - 1; -+ m_pos -= t >> 2; -+ m_pos -= *ip++ << 2; -+ TEST_LOOKBEHIND (m_pos, out); -+ NEED_OP (2); -+ *op++ = *m_pos++; -+ *op++ = *m_pos; -+ -+ goto match_done; -+ } -+ -+ TEST_LOOKBEHIND (m_pos, out); -+ NEED_OP (t + 3 - 1); -+ if (t >= 2 * 4 - (3 - 1) -+ && PTR_ALIGNED2_4 (op, m_pos)) -+ { -+ COPY4 (op, m_pos); -+ op += 4; -+ m_pos += 4; -+ t -= 4 - (3 - 1); -+ do -+ { -+ COPY4 (op, m_pos); -+ op += 4; -+ m_pos += 4; -+ t -= 4; -+ } -+ while (t >= 4); -+ if (t > 0) -+ do -+ *op++ = *m_pos++; -+ while (--t > 0); -+ } -+ else -+ -+ { -+ copy_match: -+ *op++ = *m_pos++; -+ *op++ = *m_pos++; -+ do -+ *op++ = *m_pos++; -+ while (--t > 0); -+ } -+ -+ match_done: -+ t = ip[-2] & 3; -+ -+ if (t == 0) -+ break; -+ -+ match_next: -+ NEED_OP (t); -+ NEED_IP (t + 1); -+ do -+ *op++ = *ip++; -+ while (--t > 0); -+ t = *ip++; -+ } -+ } -+ *out_len = op - out; -+ return LZO_E_EOF_NOT_FOUND; -+ -+ eof_found: -+ *out_len = op - out; -+ return (ip == ip_end ? LZO_E_OK : -+ (ip < -+ ip_end ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN)); -+ -+ input_overrun: -+ *out_len = op - out; -+ return LZO_E_INPUT_OVERRUN; -+ -+ output_overrun: -+ *out_len = op - out; -+ return LZO_E_OUTPUT_OVERRUN; -+ -+ lookbehind_overrun: -+ *out_len = op - out; -+ return LZO_E_LOOKBEHIND_OVERRUN; -+} -+ -+/* lzo1x_oo.ch */ -+ -+#define NO_LIT LZO_UINT_MAX -+ -+static void -+copy2 (lzo_byte * ip, const lzo_byte * m_pos, lzo_ptrdiff_t off) -+{ -+ ip[0] = m_pos[0]; -+ if (off == 1) -+ ip[1] = m_pos[0]; -+ else -+ ip[1] = m_pos[1]; -+} -+ -+static void -+copy3 (lzo_byte * ip, const lzo_byte * m_pos, lzo_ptrdiff_t off) -+{ -+ ip[0] = m_pos[0]; -+ if (off == 1) -+ { -+ ip[2] = ip[1] = m_pos[0]; -+ } -+ else if (off == 2) -+ { -+ ip[1] = m_pos[1]; -+ ip[2] = m_pos[0]; -+ } -+ else -+ { -+ ip[1] = m_pos[1]; -+ ip[2] = m_pos[2]; -+ } -+} -+ -+static int -+lzo1x_optimize (lzo_byte * in, lzo_uint in_len, -+ lzo_byte * out, lzo_uintp out_len, lzo_voidp wrkmem) -+{ -+ register lzo_byte *op; -+ register lzo_byte *ip; -+ register lzo_uint t; -+ register lzo_byte *m_pos; -+ lzo_uint nl; -+ const lzo_byte *const ip_end = in + in_len; -+ const lzo_byte *const op_end = out + *out_len; -+ lzo_byte *litp = NULL; -+ lzo_uint lit = 0; -+ lzo_uint next_lit = NO_LIT; -+ long o_m1_a = 0, o_m1_b = 0, o_m2 = 0, o_m3_a = 0, o_m3_b = 0; -+ -+ *out_len = 0; -+ -+ op = out; -+ ip = in; -+ -+ if (*ip > 17) -+ { -+ t = *ip++ - 17; -+ if (t < 4) -+ goto match_next; -+ goto first_literal_run; -+ } -+ -+ while (TEST_IP && TEST_OP) -+ { -+ t = *ip++; -+ if (t >= 16) -+ goto match; -+ litp = ip - 1; -+ if (t == 0) -+ { -+ t = 15; -+ while (*ip == 0) -+ t += 255, ip++; -+ t += *ip++; -+ } -+ lit = t + 3; -+ copy_literal_run: -+ *op++ = *ip++; -+ *op++ = *ip++; -+ *op++ = *ip++; -+ first_literal_run: -+ do -+ *op++ = *ip++; -+ while (--t > 0); -+ -+ t = *ip++; -+ -+ if (t >= 16) -+ goto match; -+ m_pos = op - 1 - 0x800; -+ m_pos -= t >> 2; -+ m_pos -= *ip++ << 2; -+ *op++ = *m_pos++; -+ *op++ = *m_pos++; -+ *op++ = *m_pos++; -+ lit = 0; -+ goto match_done; -+ -+ while (TEST_IP && TEST_OP) -+ { -+ if (t < 16) -+ { -+ m_pos = op - 1; -+ m_pos -= t >> 2; -+ m_pos -= *ip++ << 2; -+ -+ if (litp == NULL) -+ goto copy_m1; -+ -+ nl = ip[-2] & 3; -+ if (nl == 0 && lit == 1 && ip[0] >= 16) -+ { -+ next_lit = nl; -+ lit += 2; -+ *litp = LZO_BYTE ((*litp & ~3) | lit); -+ copy2 (ip - 2, m_pos, op - m_pos); -+ o_m1_a++; -+ } -+ else if (nl == 0 && ip[0] < 16 && ip[0] != 0 -+ && (lit + 2 + ip[0] < 16)) -+ { -+ t = *ip++; -+ *litp &= ~3; -+ copy2 (ip - 3 + 1, m_pos, op - m_pos); -+ litp += 2; -+ if (lit > 0) -+ memmove (litp + 1, litp, lit); -+ lit += 2 + t + 3; -+ *litp = LZO_BYTE (lit - 3); -+ -+ o_m1_b++; -+ *op++ = *m_pos++; -+ *op++ = *m_pos++; -+ goto copy_literal_run; -+ } -+ copy_m1: -+ *op++ = *m_pos++; -+ *op++ = *m_pos++; -+ } -+ else -+ { -+ match: -+ if (t >= 64) -+ { -+ m_pos = op - 1; -+ m_pos -= (t >> 2) & 7; -+ m_pos -= *ip++ << 3; -+ t = (t >> 5) - 1; -+ if (litp == NULL) -+ goto copy_m; -+ -+ nl = ip[-2] & 3; -+ if (t == 1 && lit > 3 && nl == 0 && -+ ip[0] < 16 && ip[0] != 0 -+ && (lit + 3 + ip[0] < 16)) -+ { -+ t = *ip++; -+ copy3 (ip - 1 - 2, m_pos, -+ op - m_pos); -+ lit += 3 + t + 3; -+ *litp = LZO_BYTE (lit - 3); -+ o_m2++; -+ *op++ = *m_pos++; -+ *op++ = *m_pos++; -+ *op++ = *m_pos++; -+ goto copy_literal_run; -+ } -+ } -+ else -+ { -+ if (t >= 32) -+ { -+ t &= 31; -+ if (t == 0) -+ { -+ t = 31; -+ while (*ip == 0) -+ t += 255, -+ ip++; -+ t += *ip++; -+ } -+ m_pos = op - 1; -+ m_pos -= *ip++ >> 2; -+ m_pos -= *ip++ << 6; -+ } -+ else -+ { -+ m_pos = op; -+ m_pos -= (t & 8) << 11; -+ t &= 7; -+ if (t == 0) -+ { -+ t = 7; -+ while (*ip == 0) -+ t += 255, -+ ip++; -+ t += *ip++; -+ } -+ m_pos -= *ip++ >> 2; -+ m_pos -= *ip++ << 6; -+ if (m_pos == op) -+ goto eof_found; -+ m_pos -= 0x4000; -+ } -+ if (litp == NULL) -+ goto copy_m; -+ -+ nl = ip[-2] & 3; -+ if (t == 1 && lit == 0 && nl == 0 -+ && ip[0] >= 16) -+ { -+ next_lit = nl; -+ lit += 3; -+ *litp = LZO_BYTE ((*litp & ~3) -+ | lit); -+ copy3 (ip - 3, m_pos, -+ op - m_pos); -+ o_m3_a++; -+ } -+ else if (t == 1 && lit <= 3 && nl == 0 -+ && ip[0] < 16 && ip[0] != 0 -+ && (lit + 3 + ip[0] < 16)) -+ { -+ t = *ip++; -+ *litp &= ~3; -+ copy3 (ip - 4 + 1, m_pos, -+ op - m_pos); -+ litp += 2; -+ if (lit > 0) -+ memmove (litp + 1, -+ litp, lit); -+ lit += 3 + t + 3; -+ *litp = LZO_BYTE (lit - 3); -+ -+ o_m3_b++; -+ *op++ = *m_pos++; -+ *op++ = *m_pos++; -+ *op++ = *m_pos++; -+ goto copy_literal_run; -+ } -+ } -+ copy_m: -+ *op++ = *m_pos++; -+ *op++ = *m_pos++; -+ do -+ *op++ = *m_pos++; -+ while (--t > 0); -+ } -+ -+ match_done: -+ if (next_lit == NO_LIT) -+ { -+ t = ip[-2] & 3; -+ lit = t; -+ litp = ip - 2; -+ } -+ else -+ t = next_lit; -+ next_lit = NO_LIT; -+ if (t == 0) -+ break; -+ match_next: -+ do -+ *op++ = *ip++; -+ while (--t > 0); -+ t = *ip++; -+ } -+ } -+ -+ *out_len = op - out; -+ return LZO_E_EOF_NOT_FOUND; -+ -+ eof_found: -+ *out_len = op - out; -+ return (ip == ip_end ? LZO_E_OK : -+ (ip < -+ ip_end ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN)); -+} -+ -+/* interface to jffs2 bbc follows */ -+ -+#include "jffs2_bbc_framework.h" -+ -+#define BLOCKSIZE 4096 -+#define OUTBLOCKSIZE (BLOCKSIZE + BLOCKSIZE / 64 + 16 + 3) -+ -+#define JFFS2_BBC_LZO_BLOCK_SIGN {0x3f, 0x47, 0x5a, 0x18} -+ -+static int -+jffs2_bbc_lzo_compressor_init (void); -+ -+static void -+jffs2_bbc_lzo_compressor_deinit (void); -+ -+static int -+jffs2_bbc_lzo_compress (void *model, unsigned char *input, -+ unsigned char *output, unsigned long *sourcelen, -+ unsigned long *dstlen); -+ -+static int -+jffs2_bbc_lzo_estimate (void *model, unsigned char *input, -+ unsigned long sourcelen, unsigned long *dstlen, -+ unsigned long *readtime, unsigned long *writetime); -+ -+static int -+jffs2_bbc_lzo_decompress (void *model, unsigned char *input, -+ unsigned char *output, unsigned long sourcelen, -+ unsigned long dstlen); -+ -+static char * -+jffs2_bbc_lzo_proc_info (void); -+ -+static int -+jffs2_bbc_lzo_proc_command (char *command); -+ -+struct jffs2_bbc_compressor_type jffs2_bbc_lzo = { -+ "lzo", -+ 0, -+ JFFS2_BBC_LZO_BLOCK_SIGN, -+ jffs2_bbc_lzo_compressor_init, -+ NULL, -+ NULL, -+ jffs2_bbc_lzo_compressor_deinit, -+ jffs2_bbc_lzo_compress, -+ jffs2_bbc_lzo_estimate, -+ jffs2_bbc_lzo_decompress, -+ jffs2_bbc_lzo_proc_info, -+ jffs2_bbc_lzo_proc_command -+}; -+ -+static int -+no_lzo1x_optimize (lzo_byte * src, lzo_uint src_len, -+ lzo_byte * dst, lzo_uintp dst_len, lzo_voidp wrkmem) -+{ -+ return 0; -+} -+ -+#ifdef __KERNEL__ -+static lzo_compress_t lzo1x_compressor = lzo1x_1_compress; -+static lzo_optimize_t lzo1x_optimizer = no_lzo1x_optimize; -+static int lzo1x_compressor_type = 1; -+static int lzo1x_optimize_type = 0; -+static unsigned long lzo1x_compressor_memsize = LZO1X_1_MEM_COMPRESS; -+#else -+static lzo_compress_t lzo1x_compressor = lzo1x_999_compress; -+static lzo_optimize_t lzo1x_optimizer = lzo1x_optimize; -+static int lzo1x_compressor_type = 999; -+static int lzo1x_optimize_type = 1; -+static unsigned long lzo1x_compressor_memsize = LZO1X_999_MEM_COMPRESS; -+#endif -+ -+static lzo_bytep wrkmem = NULL; /* temporary buffer for compression, used by lzo */ -+static lzo_bytep cmprssmem = NULL; /* temporary buffer for compression, used by interface */ -+ -+static int -+jffs2_bbc_lzo_compressor_init (void) -+{ -+ wrkmem = (lzo_bytep) jffs2_bbc_malloc (lzo1x_compressor_memsize); -+ cmprssmem = (lzo_bytep) jffs2_bbc_malloc (OUTBLOCKSIZE); -+ return !(wrkmem && cmprssmem); -+} -+ -+static void -+jffs2_bbc_lzo_compressor_deinit (void) -+{ -+ jffs2_bbc_free (wrkmem); -+ jffs2_bbc_free (cmprssmem); -+} -+ -+static int -+jffs2_bbc_lzo_compress (void *model, unsigned char *input, -+ unsigned char *output, unsigned long *sourcelen, -+ unsigned long *dstlen) -+{ -+ lzo_uint csize = OUTBLOCKSIZE; -+ lzo_uint isize = *sourcelen; -+ int retval; -+ if ((retval = -+ lzo1x_compressor (input, *sourcelen, cmprssmem, &csize, -+ wrkmem)) != LZO_E_OK) -+ { -+ *sourcelen = *dstlen = 0; -+ return retval; -+ } -+ else -+ { -+ retval = lzo1x_optimizer (cmprssmem, csize, input, &isize, -+ NULL); -+ csize += 2; -+ if (csize <= *dstlen) { -+ *dstlen = csize; -+ *(output++) = jffs2_bbc_lzo.block_sign[0]; -+ *(output++) = jffs2_bbc_lzo.block_sign[1]; -+ memcpy (output, cmprssmem, csize - 2); -+ return retval; -+ } else { -+ *sourcelen = *dstlen = 0; -+ return -1; -+ } -+ } -+} -+ -+static int -+jffs2_bbc_lzo_estimate (void *model, unsigned char *input, -+ unsigned long sourcelen, unsigned long *dstlen, -+ unsigned long *readtime, unsigned long *writetime) -+{ -+ *dstlen = sourcelen * 55 / 100; -+ *readtime = JFFS2_BBC_ZLIB_READ_TIME / 2; -+ *writetime = JFFS2_BBC_ZLIB_WRITE_TIME * 8 / 10; /* LZO1X-1 is much-much faster, -+ but LZO1X-999 is slow. The default mode for inside kernel compression is LZO1X-1 -+ This should be *0.4 really */ -+ return 0; -+} -+ -+static int -+jffs2_bbc_lzo_decompress (void *model, unsigned char *input, -+ unsigned char *output, unsigned long sourcelen, -+ unsigned long dstlen) -+{ -+ lzo_uint outlen = dstlen; -+ if ( ( *(input++) != (unsigned char)jffs2_bbc_lzo.block_sign[0] ) || -+ ( *(input++) != (unsigned char)jffs2_bbc_lzo.block_sign[1] ) -+ ) { -+ return -1; -+ } else { -+ return lzo1x_decompress (input, sourcelen - 2, output, &outlen, NULL); -+ } -+} -+ -+static char * -+jffs2_bbc_lzo_proc_info (void) -+{ -+ if (lzo1x_compressor_type == 1) -+ { -+ if (lzo1x_optimize_type == 1) -+ { -+ return "LZO1X-1 compression with optimization"; -+ } -+ else -+ { -+ return "LZO1X-1 compression without optimization"; -+ } -+ } -+ else if (lzo1x_compressor_type == 999) -+ { -+ if (lzo1x_optimize_type == 1) -+ { -+ return "LZO1X-999 compression with optimization"; -+ } -+ else -+ { -+ return "LZO1X-999 compression without optimization"; -+ } -+ } -+ else -+ { -+ return "Unknown configuration!"; -+ } -+} -+ -+static int -+jffs2_bbc_lzo_proc_command (char *command) -+{ -+ switch (*command) -+ { -+ case 'o': -+ /* switch optimization off */ -+ lzo1x_optimizer = no_lzo1x_optimize; -+ lzo1x_optimize_type = 0; -+ jffs2_bbc_print1 ("Compression optimization switched off.\n"); -+ return 0; -+ case 'O': -+ /* switch optimization on */ -+ lzo1x_optimizer = lzo1x_optimize; -+ lzo1x_optimize_type = 1; -+ jffs2_bbc_print1 ("Compression optimization switched on.\n"); -+ return 0; -+ case '1': -+ /* switch compression to LZO1X-1 */ -+ jffs2_bbc_free (wrkmem); -+ lzo1x_compressor_type = 1; -+ lzo1x_compressor = lzo1x_1_compress; -+ lzo1x_compressor_memsize = LZO1X_1_MEM_COMPRESS; -+ wrkmem = (lzo_bytep) -+ jffs2_bbc_malloc (lzo1x_compressor_memsize); -+ jffs2_bbc_print1 ("Compression type switched to LZO1X-1.\n"); -+ return 0; -+ case '9': -+ /* switch compression to LZO1X-999 */ -+ jffs2_bbc_free (wrkmem); -+ lzo1x_compressor_type = 999; -+ lzo1x_compressor = lzo1x_999_compress; -+ lzo1x_compressor_memsize = LZO1X_999_MEM_COMPRESS; -+ wrkmem = (lzo_bytep) -+ jffs2_bbc_malloc (lzo1x_compressor_memsize); -+ jffs2_bbc_print1 -+ ("Compression type switched to LZO1X-999.\n"); -+ return 0; -+ default: -+ jffs2_bbc_print1 ("Unknown command!\n"); -+ return 0; -+ } -+} -+ -+ -+struct jffs2_bbc_compressor_type * -+jffs2_bbc_lzo_init (int mode) -+{ -+ if (jffs2_bbc_register_compressor (&jffs2_bbc_lzo) == 0) -+ { -+ return &jffs2_bbc_lzo; -+ } -+ else -+ { -+ return NULL; -+ } -+} -+ -+void -+jffs2_bbc_lzo_deinit (void) -+{ -+ jffs2_bbc_unregister_compressor (&jffs2_bbc_lzo); -+} -diff -Nur linux-mips-cvs/fs/jffs2/jffs2_bbc_lzss_comp.c linux-mips/fs/jffs2/jffs2_bbc_lzss_comp.c ---- linux-mips-cvs/fs/jffs2/jffs2_bbc_lzss_comp.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-mips/fs/jffs2/jffs2_bbc_lzss_comp.c 2005-02-07 05:08:34.000000000 +0100 -@@ -0,0 +1,385 @@ -+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */ -+ -+/* -+ jffs2_bbc_lzss_comp.c -- Lempel-Ziv-Storer-Szymanski compression module for jffs2 -+ Copyright (C) 2004 Patrik Kluba -+ Based on the LZSS source included in LDS (lossless datacompression sources) -+ Block-compression modifications by Patrik Kluba -+ $Header: /openwrt/openwrt/package/linux/kernel-patches/301-jffs-compression,v 1.1 2005/03/26 10:33:31 wbx Exp $ -+*/ -+ -+/* -+Original copyright follows: -+ -+************************************************************** -+ LZSS.C -- A Data Compression Program -+************************************************************** -+ 4/6/1989 Haruhiko Okumura -+ Use, distribute, and modify this program freely. -+ Please send me your improved versions. -+ PC-VAN SCIENCE -+ NIFTY-Serve PAF01022 -+ CompuServe 74050,1022 -+************************************************************** -+ -+*/ -+ -+/* -+ -+ 2004-02-16 pajko <pajko(AT)halom(DOT)u-szeged(DOT)hu> -+ Initial release -+ -+*/ -+ -+/* lzss.c */ -+ -+#define N 4096 /* size of ring buffer */ -+#define F 18 /* upper limit for match_length */ -+#define THRESHOLD 2 /* encode string into position and length -+ if match_length is greater than this */ -+#define NIL N /* index for root of binary search trees */ -+ -+static unsigned char -+ text_buf[N + F - 1]; /* ring buffer of size N, -+ with extra F-1 bytes to facilitate string comparison */ -+static unsigned long match_position, match_length; /* of longest match. These are -+ set by the InsertNode() procedure. */ -+static unsigned long lson[N + 1], rson[N + 257], dad[N + 1]; /* left & right children & -+ parents -- These constitute binary search trees. */ -+ -+static void InitTree(void) /* initialize trees */ -+{ -+ unsigned long i; -+ -+ /* For i = 0 to N - 1, rson[i] and lson[i] will be the right and -+ left children of node i. These nodes need not be initialized. -+ Also, dad[i] is the parent of node i. These are initialized to -+ NIL (= N), which stands for 'not used.' -+ For i = 0 to 255, rson[N + i + 1] is the root of the tree -+ for strings that begin with character i. These are initialized -+ to NIL. Note there are 256 trees. */ -+ -+ for (i = N + 1; i <= N + 256; i++) rson[i] = NIL; -+ for (i = 0; i < N; i++) dad[i] = NIL; -+} -+ -+static void InsertNode(unsigned long r) -+ /* Inserts string of length F, text_buf[r..r+F-1], into one of the -+ trees (text_buf[r]'th tree) and returns the longest-match position -+ and length via the global variables match_position and match_length. -+ If match_length = F, then removes the old node in favor of the new -+ one, because the old one will be deleted sooner. -+ Note r plays double role, as tree node and position in buffer. */ -+{ -+ unsigned long i, p; -+ unsigned char *key; -+ signed long cmp; -+ -+ cmp = 1; key = &text_buf[r]; p = N + 1 + key[0]; -+ rson[r] = lson[r] = NIL; match_length = 0; -+ for ( ; ; ) { -+ if (cmp >= 0) { -+ if (rson[p] != NIL) p = rson[p]; -+ else { rson[p] = r; dad[r] = p; return; } -+ } else { -+ if (lson[p] != NIL) p = lson[p]; -+ else { lson[p] = r; dad[r] = p; return; } -+ } -+ for (i = 1; i < F; i++) -+ if ((cmp = key[i] - text_buf[p + i]) != 0) break; -+ if (i > match_length) { -+ match_position = p; -+ if ((match_length = i) >= F) break; -+ } -+ } -+ dad[r] = dad[p]; lson[r] = lson[p]; rson[r] = rson[p]; -+ dad[lson[p]] = r; dad[rson[p]] = r; -+ if (rson[dad[p]] == p) rson[dad[p]] = r; -+ else lson[dad[p]] = r; -+ dad[p] = NIL; /* remove p */ -+} -+ -+static void DeleteNode(unsigned long p) /* deletes node p from tree */ -+{ -+ unsigned long q; -+ -+ if (dad[p] == NIL) return; /* not in tree */ -+ if (rson[p] == NIL) q = lson[p]; -+ else if (lson[p] == NIL) q = rson[p]; -+ else { -+ q = lson[p]; -+ if (rson[q] != NIL) { -+ do { q = rson[q]; } while (rson[q] != NIL); -+ rson[dad[q]] = lson[q]; dad[lson[q]] = dad[q]; -+ lson[q] = lson[p]; dad[lson[p]] = q; -+ } -+ rson[q] = rson[p]; dad[rson[p]] = q; -+ } -+ dad[q] = dad[p]; -+ if (rson[dad[p]] == p) rson[dad[p]] = q; else lson[dad[p]] = q; -+ dad[p] = NIL; -+} -+ -+/* modified for block compression */ -+/* on return, srclen will contain the number of successfully compressed bytes -+ and dstlen will contain completed compressed bytes */ -+ -+static int Encode(unsigned char *srcbuf, unsigned char *dstbuf, unsigned long *srclen, -+ unsigned long *dstlen) -+{ -+ unsigned long i, len, r, c, s, last_match_length, code_buf_ptr; -+ unsigned char code_buf[17], mask; -+ unsigned char *ip, *op; -+ unsigned long written = 0; -+ unsigned long read = 0; -+ unsigned char *srcend = srcbuf + *srclen; -+ unsigned char *dstend = dstbuf + *dstlen; -+ ip = srcbuf; -+ op = dstbuf; -+ InitTree(); /* initialize trees */ -+ code_buf[0] = 0; /* code_buf[1..16] saves eight units of code, and -+ code_buf[0] works as eight flags, "1" representing that the unit -+ is an unencoded letter (1 byte), "0" a position-and-length pair -+ (2 bytes). Thus, eight units require at most 16 bytes of code. */ -+ code_buf_ptr = mask = 1; -+ s = 0; r = N - F; -+ for (i = s; i < r; i++) text_buf[i] = ' '; /* Clear the buffer with -+ any character that will appear often. */ -+ for (len = 0; (len < F) && (ip < srcend); len++) -+ text_buf[r + len] = *(ip++); /* Read F bytes into the last F bytes of -+ the buffer */ -+ read = len; -+ for (i = 1; i <= F; i++) InsertNode(r - i); /* Insert the F strings, -+ each of which begins with one or more 'space' characters. Note -+ the order in which these strings are inserted. This way, -+ degenerate trees will be less likely to occur. */ -+ InsertNode(r); /* Finally, insert the whole string just read. The -+ global variables match_length and match_position are set. */ -+ do { -+ if (match_length > len) match_length = len; /* match_length -+ may be spuriously long near the end of text. */ -+ if (match_length <= THRESHOLD) { -+ match_length = 1; /* Not long enough match. Send one byte. */ -+ code_buf[0] |= mask; /* 'send one byte' flag */ -+ code_buf[code_buf_ptr++] = text_buf[r]; /* Send uncoded. */ -+ } else { -+ code_buf[code_buf_ptr++] = match_position; -+ code_buf[code_buf_ptr++] = (((match_position >> 4) & 0xf0) -+ | (match_length - (THRESHOLD + 1))); /* Send position and -+ length pair. Note match_length > THRESHOLD. */ -+ } -+ if ((mask <<= 1) == 0) { /* Shift mask left one bit. */ -+ if ((op + code_buf_ptr) > dstend) { -+ *dstlen = written; /* written contains bytes of complete compressed -+ code */ -+ return -1; -+ }; -+ for (i = 0; i < code_buf_ptr; *(op++) = code_buf[i++]); /* Send at most 8 units of */ -+ /* code together */ -+ written += code_buf_ptr; -+ *srclen = read; /* this many bytes have been successfully compressed */ -+ code_buf[0] = 0; code_buf_ptr = mask = 1; -+ } -+ last_match_length = match_length; -+ for (i = 0; (i < last_match_length) && (ip < srcend); i++) { -+ c = *(ip++); -+ DeleteNode(s); /* Delete old strings and */ -+ text_buf[s] = c; /* read new bytes */ -+ if (s < F - 1) text_buf[s + N] = c; /* If the position is -+ near the end of buffer, extend the buffer to make -+ string comparison easier. */ -+ s = (s + 1) & (N - 1); r = (r + 1) & (N - 1); -+ /* Since this is a ring buffer, increment the position -+ modulo N. */ -+ InsertNode(r); /* Register the string in text_buf[r..r+F-1] */ -+ } -+ read += i; -+ while (i++ < last_match_length) { /* After the end of text, */ -+ DeleteNode(s); /* no need to read, but */ -+ s = (s + 1) & (N - 1); r = (r + 1) & (N - 1); -+ if (--len) InsertNode(r); /* buffer may not be empty. */ -+ } -+ } while (len > 0); /* until length of string to be processed is zero */ -+ if (code_buf_ptr > 1) { /* Send remaining code. */ -+ if ((op + code_buf_ptr) > dstend) { -+ *dstlen = written; -+ return -1; -+ } -+ for (i = 0; i < code_buf_ptr; *(op++) = code_buf[i++]); -+ written += code_buf_ptr; -+ *srclen = read; -+ } -+ *dstlen = written; -+ return 0; -+} -+ -+static int Decode(unsigned char *srcbuf, unsigned char *dstbuf, unsigned long srclen, -+ unsigned long dstlen) /* Just the reverse of Encode(). */ -+{ -+ unsigned long i, r, c, j, k, flags; -+ unsigned char *ip, *op; -+ unsigned long written; -+ unsigned long read; -+ unsigned char *srcend = srcbuf + srclen; -+ unsigned char *dstend = dstbuf + dstlen; -+ read = written = 0; -+ ip = srcbuf; -+ op = dstbuf; -+ for (i = 0; i < N - F; i++) text_buf[i] = ' '; -+ r = N - F; flags = 0; -+ for ( ; ; ) { -+ if (((flags >>= 1) & 256) == 0) { -+ if (ip >= srcend) return 0; -+ c = *(ip++); -+ flags = c | 0xff00; /* uses higher byte cleverly */ -+ } /* to count eight */ -+ if (flags & 1) { -+ if (ip >= srcend) return 0; -+ c = *(ip++); -+ if (op >= dstend) return -1; -+ *(op++) = text_buf[r++] = c; r &= (N - 1); -+ } else { -+ if ((ip + 2) > srcend) return 0; -+ i = *(ip++); -+ j = *(ip++); -+ i |= ((j & 0xf0) << 4); j = (j & 0x0f) + THRESHOLD; -+ if ((op + j + 1) > dstend) return -1; -+ for (k = 0; k <= j; k++) { -+ c = text_buf[(i + k) & (N - 1)]; -+ *(op++) = text_buf[r++] = c; r &= (N - 1); -+ } -+ } -+ } -+} -+ -+/* interface to jffs2 bbc follows */ -+ -+#include "jffs2_bbc_framework.h" -+ -+ -+#define JFFS2_BBC_LZSS_BLOCK_SIGN {0x27, 0x6f, 0x12, 0xc4} -+ -+static int -+jffs2_bbc_lzss_compressor_init (void); -+ -+static void -+jffs2_bbc_lzss_compressor_deinit (void); -+ -+static int -+jffs2_bbc_lzss_compress (void *model, unsigned char *input, -+ unsigned char *output, unsigned long *sourcelen, -+ unsigned long *dstlen); -+ -+static int -+jffs2_bbc_lzss_estimate (void *model, unsigned char *input, -+ unsigned long sourcelen, unsigned long *dstlen, -+ unsigned long *readtime, unsigned long *writetime); -+ -+static int -+jffs2_bbc_lzss_decompress (void *model, unsigned char *input, -+ unsigned char *output, unsigned long sourcelen, -+ unsigned long dstlen); -+ -+static char * -+jffs2_bbc_lzss_proc_info (void); -+ -+static int -+jffs2_bbc_lzss_proc_command (char *command); -+ -+struct jffs2_bbc_compressor_type jffs2_bbc_lzss = { -+ "lzss", -+ 0, -+ JFFS2_BBC_LZSS_BLOCK_SIGN, -+ jffs2_bbc_lzss_compressor_init, -+ NULL, -+ NULL, -+ jffs2_bbc_lzss_compressor_deinit, -+ jffs2_bbc_lzss_compress, -+ jffs2_bbc_lzss_estimate, -+ jffs2_bbc_lzss_decompress, -+ jffs2_bbc_lzss_proc_info, -+ jffs2_bbc_lzss_proc_command -+}; -+ -+static int -+jffs2_bbc_lzss_compressor_init (void) -+{ -+ return 0; -+} -+ -+static void -+jffs2_bbc_lzss_compressor_deinit (void) -+{ -+} -+ -+static int -+jffs2_bbc_lzss_compress (void *model, unsigned char *input, -+ unsigned char *output, unsigned long *sourcelen, -+ unsigned long *dstlen) -+{ -+ int retval; -+ unsigned long dst = *dstlen; -+ *(output++) = jffs2_bbc_lzss.block_sign[0]; -+ *(output++) = jffs2_bbc_lzss.block_sign[1]; -+ dst -= 2; -+ retval = Encode(input, output, sourcelen, &dst); -+ dst += 2; -+ *dstlen = dst; -+ return retval; -+} -+ -+static int -+jffs2_bbc_lzss_estimate (void *model, unsigned char *input, -+ unsigned long sourcelen, unsigned long *dstlen, -+ unsigned long *readtime, unsigned long *writetime) -+{ -+ *dstlen = sourcelen * 60 / 100; -+ *readtime = JFFS2_BBC_ZLIB_READ_TIME * 12 / 10; -+ *writetime = JFFS2_BBC_ZLIB_WRITE_TIME * 3; -+ return 0; -+} -+ -+static int -+jffs2_bbc_lzss_decompress (void *model, unsigned char *input, -+ unsigned char *output, unsigned long sourcelen, -+ unsigned long dstlen) -+{ -+ if ( ( *(input++) != (unsigned char)jffs2_bbc_lzss.block_sign[0] ) || -+ ( *(input++) != (unsigned char)jffs2_bbc_lzss.block_sign[1] ) -+ ) { -+ return -1; -+ } else { -+ return Decode(input, output, sourcelen - 2, dstlen); -+ } -+} -+ -+static char * -+jffs2_bbc_lzss_proc_info (void) -+{ -+ return "Lempel-Ziv-Storer-Szymanski compression module"; -+} -+ -+static int -+jffs2_bbc_lzss_proc_command (char *command) -+{ -+ return 0; -+} -+ -+struct jffs2_bbc_compressor_type * -+jffs2_bbc_lzss_init (int mode) -+{ -+ if (jffs2_bbc_register_compressor (&jffs2_bbc_lzss) == 0) -+ { -+ return &jffs2_bbc_lzss; -+ } -+ else -+ { -+ return NULL; -+ } -+} -+ -+void -+jffs2_bbc_lzss_deinit (void) -+{ -+ jffs2_bbc_unregister_compressor (&jffs2_bbc_lzss); -+} -diff -Nur linux-mips-cvs/fs/jffs2/linux-2.4.25.hpatch linux-mips/fs/jffs2/linux-2.4.25.hpatch ---- linux-mips-cvs/fs/jffs2/linux-2.4.25.hpatch 1970-01-01 01:00:00.000000000 +0100 -+++ linux-mips/fs/jffs2/linux-2.4.25.hpatch 2005-02-07 05:08:34.000000000 +0100 -@@ -0,0 +1,97 @@ -+FMakefile -+=BBC insertion -+-COMPR_OBJS -+iMakefile.bbc.inc -++ -+I -+?JFFS2_OBJS -++ $(JFFS2_BBC_KERNEL_OBJS) \ -+ -+F../Config.in -+=BBC insertion -+-tristate 'Compressed ROM file system support' CONFIG_CRAMFS -+iConfig.in.bbc.inc -++ -+I -+F../../Documentation/Configure.help -+=BBC insertion -+-JFFS stats available -+iConfigure.help.bbc.inc -++ -+I -+Fcompr_zlib.c -+=(de)compress->(de)compress2 -+-int zlib_compress(unsigned char *data_in, unsigned char *cpage_out, -++int jffs2_zlib_compress2(unsigned char *data_in, unsigned char *cpage_out, -+-void zlib_decompress(unsigned char *data_in, unsigned char *cpage_out, -++void jffs2_zlib_decompress2(unsigned char *data_in, unsigned char *cpage_out, -+?inflateEnd(&strm); -+?} -++ -++extern int jffs2_zlib_compress(unsigned char *data_in, unsigned char *cpage_out, __u32 * sourcelen, __u32 * dstlen); -++extern void jffs2_zlib_decompress(unsigned char *data_in, unsigned char *cpage_out, __u32 srclen, __u32 destlen); -++ -++int zlib_compress(unsigned char *data_in, unsigned char *cpage_out, -++ __u32 *sourcelen, __u32 *dstlen) -++{ -++ return jffs2_zlib_compress(data_in,cpage_out,sourcelen,dstlen); -++} -++ -++void zlib_decompress(unsigned char *data_in, unsigned char *cpage_out, -++ __u32 srclen, __u32 destlen) -++{ -++ jffs2_zlib_decompress(data_in,cpage_out,srclen,destlen); -++} -++ -+ -+Ffile.c -+=set_act_sb before write -+-#include -++#include "jffs2_bbc_framework.h" /**BBC**/ -+I -+?int jffs2_commit_write -+-jffs2_compress( -++ jffs2_bbc_model_set_act_sb(c); /**BBC**/ -+I -+ -+Fgc.c -+=set_act_sb before write -+-#include -++#include "jffs2_bbc_framework.h" /**BBC**/ -+I -+?int jffs2_garbage_collect_dnode( -+-jffs2_compress( -++ jffs2_bbc_model_set_act_sb(c); /**BBC**/ -+I -+ -+Fread.c -+=set_act_sb before read -+-#include -++#include "jffs2_bbc_framework.h" /**BBC**/ -+I -+?int jffs2_read_dnode( -+-jffs2_decompress( -++ jffs2_bbc_model_set_act_sb(c); /**BBC**/ -+I -+ -+Fsuper.c -+=init, load_model -+-#include -++#include "jffs2_bbc_fs.h" /**BBC**/ -+I -+?struct super_block *jffs2_read_super( -+-return sb; -++ jffs2_bbc_load_model(sb); /**BBC**/ -+I -+?void jffs2_put_super -+?c = JFFS2_SB_INFO -++ jffs2_bbc_unload_model(sb); /**BBC**/ -+?init_jffs2_fs(void) -+?int ret; -++ -++ jffs2_bbc_proc_init(); /**BBC**/ -++ -+?exit_jffs2_fs(void) -+?{ -++ jffs2_bbc_proc_deinit(); /**BBC**/ -++ -diff -Nur linux-mips-cvs/fs/jffs2/read.c linux-mips/fs/jffs2/read.c ---- linux-mips-cvs/fs/jffs2/read.c 2003-11-17 02:07:44.000000000 +0100 -+++ linux-mips/fs/jffs2/read.c 2005-02-07 05:08:35.000000000 +0100 -@@ -35,6 +35,7 @@ - * - */ - -+#include "jffs2_bbc_framework.h" /**BBC**/ - #include <linux/kernel.h> - #include <linux/slab.h> - #include <linux/jffs2.h> -@@ -140,6 +141,7 @@ - D2(printk(KERN_DEBUG "Data CRC matches calculated CRC %08x\n", crc)); - if (ri->compr != JFFS2_COMPR_NONE) { - D2(printk(KERN_DEBUG "Decompress %d bytes from %p to %d bytes at %p\n", ri->csize, readbuf, ri->dsize, decomprbuf)); -+ jffs2_bbc_model_set_act_sb(c); /**BBC**/ - ret = jffs2_decompress(ri->compr, readbuf, decomprbuf, ri->csize, ri->dsize); - if (ret) { - printk(KERN_WARNING "Error: jffs2_decompress returned %d\n", ret); -diff -Nur linux-mips-cvs/fs/jffs2/super.c linux-mips/fs/jffs2/super.c ---- linux-mips-cvs/fs/jffs2/super.c 2003-01-11 18:53:17.000000000 +0100 -+++ linux-mips/fs/jffs2/super.c 2005-02-07 05:08:35.000000000 +0100 -@@ -35,6 +35,7 @@ - * - */ - -+#include "jffs2_bbc_fs.h" /**BBC**/ - #include <linux/config.h> - #include <linux/kernel.h> - #include <linux/module.h> -@@ -272,6 +273,7 @@ - sb->s_magic = JFFS2_SUPER_MAGIC; - if (!(sb->s_flags & MS_RDONLY)) - jffs2_start_garbage_collect_thread(c); -+ jffs2_bbc_load_model(sb); /**BBC**/ - return sb; - - out_root_i: -@@ -288,6 +290,7 @@ - void jffs2_put_super (struct super_block *sb) - { - struct jffs2_sb_info *c = JFFS2_SB_INFO(sb); -+ jffs2_bbc_unload_model(sb); /**BBC**/ - - D2(printk(KERN_DEBUG "jffs2: jffs2_put_super()\n")); - -@@ -344,6 +347,9 @@ - { - int ret; - -+ jffs2_bbc_proc_init(); /**BBC**/ -+ -+ - printk(KERN_NOTICE "JFFS2 version 2.1. (C) 2001 Red Hat, Inc., designed by Axis Communications AB.\n"); - - #ifdef JFFS2_OUT_OF_KERNEL -@@ -388,6 +394,8 @@ - - static void __exit exit_jffs2_fs(void) - { -+ jffs2_bbc_proc_deinit(); /**BBC**/ -+ - jffs2_destroy_slab_caches(); - jffs2_zlib_exit(); - unregister_filesystem(&jffs2_fs_type); |