4580089 [rkeene@sledge /home/rkeene/devel/dact]$ cat -n comp_mzlib2.c
  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
4580090 [rkeene@sledge /home/rkeene/devel/dact]$

Click here to go back to the directory listing.
Click here to download this file.
last modified: 2004-04-04 07:01:50