1 /* 2 * Copyright (C) 2001, 2002, and 2003 Roy Keene 3 * 4 * This program is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU General Public License 6 * as published by the Free Software Foundation; either version 2 7 * of the License, or (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program; if not, write to the Free Software 16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 * 18 * email: dact@rkeene.org 19 */ 20 21 22 /* 23 Compress by gathering bytes that are most often placed near each other 24 and rearranging the ASCII Charectar Set to make those bytes have 25 similar values. 26 27 */ 28 29 30 #include "dact.h" 31 #include "comp_mzlib2.h" 32 #ifndef comp_mzlib2_algo 33 34 #ifdef HAVE_LIBZ 35 #ifdef HAVE_ZLIB_H 36 #include <zlib.h> 37 #endif 38 #include <stdio.h> 39 #ifdef HAVE_UNISTD_H 40 #include <unistd.h> 41 #endif 42 #ifdef HAVE_STDLIB_H 43 #include <stdlib.h> 44 #endif 45 #ifdef HAVE_STRING_H 46 #include <string.h> 47 #endif 48 #include "sort.h" 49 #define SQRD_256 65536 50 51 52 /* 53 mode - DACT_MODE_COMPR or DACT_MODE_DECMP 54 Determine whether to compress or decompress. 55 prev_block - Previous (uncompressed) block. 56 curr_block - The data to be compressed. 57 out_block - Where to put data after compression. 58 blk_size - Size of prev_block and curr_block. 59 */ 60 #if defined(USE_MODULES) && defined(AS_MODULE) 61 #include "module.h" 62 uint32_t DC_NUM=8; 63 uint32_t DC_TYPE=DACT_MOD_TYPE_COMP; 64 void *DC_ALGO=comp_mzlib2_algo; 65 char *DC_NAME="Second Modified Zlib Compression (MOD)"; 66 #endif 67 68 #ifdef DEBUG 69 #if DEBUG>=2 70 #define MAKE_MZLIB2 1 71 #endif 72 #endif 73 74 #ifdef MAKE_MZLIB2 75 int comp_mzlib2_algo(int mode, unsigned char *prev_block, unsigned char *curr_block, char *out_block, int blk_size, int bufsize) { 76 switch(mode) { 77 case DACT_MODE_COMPR: 78 return(comp_mzlib2_compress(prev_block, curr_block, out_block, blk_size, bufsize)); 79 break; /* Heh */ 80 case DACT_MODE_DECMP: 81 return(comp_mzlib2_decompress(prev_block, curr_block, out_block, blk_size, bufsize)); 82 break; 83 default: 84 printf("Unsupported mode: %i\n", mode); 85 return(-1); 86 } 87 } 88 #else 89 int comp_mzlib2_algo(int mode, unsigned char *prev_block, unsigned char *curr_block, char *out_block, int blk_size, int bufsize) { 90 return(-1); 91 } 92 #endif 93 94 int comp_mzlib2_compress(unsigned char *prev_block, unsigned char *curr_block, char *out_block, int blk_size, int bufsize) { 95 unsigned long dest_size; 96 unsigned char *tmp_block; 97 uint32_t freq[SQRD_256]; 98 uint16_t lookup_table[SQRD_256], curr_val, repl_val; 99 int i, cnt, m=2, retval, low_byte=0, x; 100 101 memset(freq,0,sizeof(freq)); 102 103 for (i=0;i<blk_size;i+=2) { 104 x=(curr_block[i]<<8)|(curr_block[i+1]); 105 freq[x]++; 106 if (freq[x]==0xffff) return(-1); 107 } 108 109 110 int_sort_fast(freq, SQRD_256, 0); 111 112 for (i=0;i<(SQRD_256);i++) { 113 if ((freq[i]&0xffff)!=0) { 114 out_block[m++]=freq[i]>>24; 115 out_block[m++]=(freq[i]>>16)&0xff; 116 if (m>=(blk_size*2)) { 117 return(-1); 118 } 119 lookup_table[freq[i]>>16]=i; 120 PRINT_LINE; fprintf(stderr, "%04x: 0x%02x and 0x%02x are near each other %i times\n",i,(freq[i]>>24),(freq[i]>>16)&0xff,freq[i]&0xffff); 121 } else { 122 break; 123 } 124 } 125 126 cnt=(m-2); 127 out_block[0]=((m-2)>>8); 128 out_block[1]=((m-2)&0xff); 129 if ((m-2)<0x200) low_byte=1; 130 131 for (i=0;i<blk_size;i+=2) { 132 curr_val=((curr_block[i]<<8)| curr_block[i+1]); 133 repl_val=lookup_table[curr_val]; 134 if (!low_byte) 135 out_block[m++]=repl_val>>8; 136 out_block[m++]=repl_val&0xff; 137 SPOTVAR_NUM(m); 138 if (m>=(blk_size*2)) return(-1); 139 } 140 141 dest_size=(int) ((float) ((m*1.02)+15)); 142 SPOTVAR_NUM(dest_size); 143 if ((tmp_block=malloc(dest_size))==NULL) { 144 return(-1); 145 } 146 memcpy(tmp_block,out_block,m); 147 /* 148 for (i=0;i<m;i++) { 149 printf("%02x ", tmp_block[i]); 150 if (i==(cnt+2)) printf("-- "); 151 if (((i+1)%25)==0) printf("\n"); 152 } 153 printf("\n\n"); 154 */ 155 156 /* 157 for (i=0;i<blk_size;i++) printf("%02x ", curr_block[i]); 158 printf("\n"); 159 */ 160 161 retval=compress(out_block, &dest_size, tmp_block, m); 162 if (retval!=Z_OK) { 163 return(blk_size*2); 164 } 165 166 free(tmp_block); 167 return(dest_size); 168 } 169 170 int comp_mzlib2_decompress(unsigned char *prev_block, unsigned char *curr_block, unsigned char *out_block, int blk_size, int bufsize) { 171 uint16_t lookup_table[SQRD_256], curr_val, repl_val; 172 unsigned long dest_size=(blk_size*2); 173 unsigned char *tmp_block; 174 unsigned int m=0, hdrsize; 175 int retval, i, low_byte=0; 176 177 tmp_block=malloc(dest_size); 178 retval=uncompress(tmp_block,&dest_size,curr_block,blk_size); 179 180 if (retval!=Z_OK) return(0); 181 182 hdrsize=((unsigned int) (((tmp_block[0]<<8)|tmp_block[1])))+2; 183 184 if ((hdrsize-2)<0x200) low_byte=1; 185 186 for (i=2;i<hdrsize;i+=2) { 187 lookup_table[(i-2)/2]=((tmp_block[i]<<8)|tmp_block[i+1]); 188 } 189 190 for (i=hdrsize;i<(dest_size);i+=(2-low_byte)) { 191 if (low_byte) { 192 curr_val=tmp_block[i]; 193 } else { 194 curr_val=((tmp_block[i]<<8)|tmp_block[i+1]); 195 } 196 repl_val=lookup_table[curr_val]; 197 out_block[m++]=repl_val>>8; 198 out_block[m++]=repl_val&0xff; 199 } 200 201 /* 202 for (i=0;i<m;i++) printf("%02x ", out_block[i]); 203 printf("\n"); 204 */ 205 206 free(tmp_block); 207 return(m); 208 } 209 #endif 210 211 #endif |