summaryrefslogtreecommitdiff
path: root/other/wrez/compressor.c
diff options
context:
space:
mode:
authorRoot THC2026-02-24 12:42:47 +0000
committerRoot THC2026-02-24 12:42:47 +0000
commitc9cbeced5b3f2bdd7407e29c0811e65954132540 (patch)
treeaefc355416b561111819de159ccbd86c3004cf88 /other/wrez/compressor.c
parent073fe4bf9fca6bf40cef2886d75df832ef4b6fca (diff)
initial
Diffstat (limited to 'other/wrez/compressor.c')
-rw-r--r--other/wrez/compressor.c466
1 files changed, 466 insertions, 0 deletions
diff --git a/other/wrez/compressor.c b/other/wrez/compressor.c
new file mode 100644
index 0000000..91f3569
--- /dev/null
+++ b/other/wrez/compressor.c
@@ -0,0 +1,466 @@
1
2/* ripped from:
3 * kim holviala (kimmy/pulp)
4 * sed
5 *
6 * i'm sorry for ripping this, but as i just cut code from it, it does not
7 * matter that much gpl-wise. uhhohh.
8 */
9
10#include <stdio.h>
11#include <stdlib.h>
12#include <string.h>
13
14
15#define byte unsigned char
16#define word unsigned short
17#define dword unsigned long
18
19#define OK 0
20#define ERROR 1
21
22#define MAXSIZE 20000
23
24#define TRUE 1
25#define FALSE 0
26
27
28byte _buffer[MAXSIZE], lzbuffer[MAXSIZE];
29byte * buffer=0;
30word lenght=0, lzlenght=0, hufflimit1=0, hufflimit2=0, lenlimit=0, decodelenght=0;
31int maxhuffman=0, dummy=0;
32int bitpos=0;
33
34char *rotorchar = "-/|\\";
35
36char *info = "Six-2-Four v1.0 - Exepacker for 4Kb-intros.\n"
37 "Copyright (c) Kim Holviala a.k.a Kimmy/PULP Productions 1997.\n"
38 "Linux version - Sed (sed@free.fr) october 1999\n"
39 " Licenced under the terms of the GNU General Public Licence.\n";
40
41char *help = " Usage: 624 [-s] infile [outfile]\n\n"
42 " Where: -s - use super duper compression\n"
43 " infile - tinlinked file shorter than 20000 bytes\n"
44 "This program is EMAILWARE. You're free to use this even with commercial\n"
45 "programs, AFTER you email me to <kimmy@iki.fi> and tell me the name of\n"
46 "your favorite dark beer!\n"
47 "The Linux version you are running in licenced under the terms\nof the GNU General Public Licence.\n"
48 "It requires nasm (available at http://www.web-sites.co.uk/nasm/index.html)\n"
49 "and tinlink 1.0 (available at http://sed.free.fr/tinlink/index.html)\n";
50
51
52
53/*ħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħ
54 *
55 * Write one bit to the lzbuffer
56 *
57 *ħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħ*/
58
59void writebit(word bit) {
60 byte mask = 1;
61
62 mask <<= bitpos;
63
64 if (bit == 0) lzbuffer[lzlenght] &= 255-mask;
65 else lzbuffer[lzlenght] |= mask;
66
67 if (++bitpos > 7) {
68
69 bitpos = 0;
70 lzlenght++;
71
72 /* it's possible to have a bigger file than the original, in that case,
73 * we must stop
74 */
75 if (lzlenght >= MAXSIZE) {
76 fprintf(stderr, "\nSorry, but the compressed file would be too big.\n");
77 exit(1);
78 }
79 }
80}
81
82
83
84/*ħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħ
85 *
86 * Write n bits to the lzbuffer
87 *
88 *ħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħ*/
89
90void writedata(word b, word mask) {
91
92 do {
93 writebit(b & mask);
94 mask >>= 1;
95
96 } while (mask > 0);
97}
98
99
100
101/*ħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħ
102 *
103 * Write one "huffman"-coded number to the lzbuffer
104 *
105 *ħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħ*/
106
107void writehuffman(word number) {
108
109 word mask;
110
111
112 number--;
113
114 if (number < (hufflimit1 * 2)) {
115
116 writebit(0);
117 mask = hufflimit1;
118 }
119 else {
120 number -= (hufflimit1 * 2);
121
122 writebit(1);
123 mask = hufflimit2;
124 }
125
126
127 do {
128 writebit(number & mask);
129 mask >>= 1;
130
131 } while (mask > 0);
132}
133
134
135
136/*ħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħ
137 *
138 * Return log2 (if that's what it is?)
139 *
140 *ħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħ*/
141
142word log2(word l) {
143
144 switch (l) {
145 case 1: return 0;
146 case 2: return 1;
147 case 4: return 2;
148 case 8: return 3;
149 case 16: return 4;
150 case 32: return 5;
151 case 64: return 6;
152 case 128: return 7;
153 case 256: return 8;
154 case 512: return 9;
155 case 1024: return 10;
156 case 2048: return 11;
157 case 4096: return 12;
158 }
159
160 return 0;
161}
162
163
164
165/*ħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħ
166 *
167 * Compress the file
168 *
169 *ħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħ*/
170
171void squeeze(void) {
172
173 int count1=0, count2=0;
174 word bestlen=0, bestpos=0, len=0;
175 byte b=0;
176
177
178 lzlenght = 0;
179 bitpos=0;
180
181 for (count1 = 0; count1 < lenght; count1++) {
182
183 bestlen = 0;
184 b = buffer[count1];
185
186 for (count2 = (count1 - 1); count2 > (count1 - maxhuffman); count2--) {
187
188 if (count2 < 0) break;
189
190 if (buffer[count2] == b) {
191
192 for (len = 1; len < maxhuffman; len ++) {
193
194 if ((count1 + len) > lenght) break;
195 if (buffer[count1 + len] != buffer[count2 + len]) break;
196 }
197
198 if (len > bestlen) {
199
200 bestlen = len;
201 bestpos = count1 - count2;
202 }
203 }
204
205 }
206
207 if (bestlen == 1 && bestpos < 17) {
208
209 writebit(1);
210 writebit(0);
211 writedata(bestpos - 1, 8);
212
213 continue;
214 }
215
216 if (bestlen > 1) {
217
218 if (bestlen < lenlimit) {
219
220 for (count2 = 0; count2 < bestlen; count2++) writebit(1);
221 writebit(0);
222 }
223 else {
224 for (count2 = 0; count2 < lenlimit; count2++) writebit(1);
225 writehuffman(bestlen - 1);
226 }
227
228 count1 += bestlen - 1;
229 writehuffman(bestpos);
230
231 continue;
232 }
233
234 writebit(0);
235 writedata(b, 128);
236 }
237
238 lzlenght++;
239}
240
241
242
243/*ħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħ
244 *
245 * Find the best compression values
246 *
247 *ħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħ*/
248
249void compress(void) {
250
251 word besthl1=0, besthl2=0, bestll=0, bestlzlen;
252 byte rotor = 0;
253
254
255 lenlimit = 9;
256 bestlzlen = 60000;
257
258 for (hufflimit1 = 4; hufflimit1 <= 64; hufflimit1 *= 2)
259 for (hufflimit2 = hufflimit1 * 4; hufflimit2 <= 2048; hufflimit2 *= 2) {
260
261 fflush(stdout);
262 rotor++;
263 rotor&=3;
264
265 maxhuffman = (hufflimit2 + hufflimit1) * 2;
266
267 squeeze();
268
269 if (lzlenght < bestlzlen) {
270
271 besthl1 = hufflimit1;
272 besthl2 = hufflimit2;
273 bestlzlen = lzlenght;
274 }
275 }
276
277 hufflimit1 = besthl1;
278 hufflimit2 = besthl2;
279 maxhuffman = (hufflimit2 + hufflimit1) * 2;
280 bestlzlen = 60000;
281
282 for (lenlimit = 5; lenlimit <= 15; lenlimit++) {
283
284 fflush(stdout);
285 rotor++;
286 rotor&=3;
287
288 squeeze();
289
290 if (lzlenght < bestlzlen) {
291
292 bestll = lenlimit;
293 bestlzlen = lzlenght;
294 }
295 }
296
297 lenlimit = bestll;
298
299 squeeze();
300}
301
302
303
304/*ħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħ
305 *
306 * Main
307 *
308 *ħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħ*/
309
310int
311main (int argc, char *argv[])
312{
313 FILE *out;
314 FILE *fp;
315 char *destfile="un624.linux.compressed.bin.712SAk", *srcfile, slow;
316 char *aoutfile="a.out";
317 long ratio;
318 unsigned long starting_offset, new_offset, memory;
319 char tin[1024];
320
321 buffer=_buffer;
322
323
324 if (argc<2) {
325 puts(help);
326 fprintf(stderr, "Bad number of arguments.\n");
327 return ERROR;
328 }
329
330 if (argv[1][0] == '-') {
331 if (argv[1][1] != 's' || argv[1][2]) {
332 puts(help);
333 fprintf(stderr, "Unkown option '%s'\n", argv[1]);
334 return ERROR;
335 }
336 if (argc < 3 || argc > 4) {
337 puts(help);
338 fprintf(stderr, "Bad number of arguments.\n");
339 return ERROR;
340 }
341 slow = TRUE;
342 srcfile = argv[2];
343 if (argc==4)
344 aoutfile=argv[3];
345 }
346 else {
347 if (argc < 2 || argc > 3) {
348 puts(help);
349 fprintf(stderr, "Bad number of arguments.\n");
350 return ERROR;
351 }
352 slow = FALSE;
353 srcfile = argv[1];
354 if (argc==3)
355 aoutfile=argv[2];
356 }
357
358
359 if ((fp = fopen(srcfile, "rb")) == NULL) {
360
361 printf("File not found!\n");
362 return ERROR;
363 }
364
365 lenght = (word) fread(buffer, 1, MAXSIZE, fp);
366 if (lenght == 0) {
367
368 printf("Error reading from file!\n");
369 fclose(fp);
370
371 return ERROR;
372 }
373
374#if 0
375 lenght-=74;
376 buffer+=74;
377#endif
378
379#if 0
380 if (fread(&dummy, 1, 1, fp) != 0) {
381 printf("File too big (must be < 20000 bytes)!\n");
382 fclose(fp);
383 return ERROR;
384 }
385#endif
386
387 fclose(fp);
388
389
390 if (slow == TRUE) compress();
391 else {
392 hufflimit1 = 16;
393 hufflimit2 = 128;
394 lenlimit = 9;
395 maxhuffman = (hufflimit2 + hufflimit1) * 2;
396 squeeze();
397 }
398
399
400 if ((fp = fopen(aoutfile, "wb")) == NULL) {
401 printf("Cannot create file '%s'\n", aoutfile);
402 return ERROR;
403 }
404 fwrite(lzbuffer, 1, lzlenght, fp);
405 fclose(fp);
406
407 printf ("%d:%d:%d:%d:%d\n",
408 lzlenght, lenlimit-1, log2(hufflimit1)+1, log2(hufflimit2)+1, (hufflimit1 * 2)+1);
409#if 0
410 fprintf (stderr, "%%define data_length %d\n"
411 "%%define llstuff %d\n"
412 "%%define hl1stuff %d\n"
413 "%%define hl2stuff %d\n"
414 "%%define hf2stuff %d\n",
415 lzlenght, lenlimit-1, log2(hufflimit1)+1, log2(hufflimit2)+1, (hufflimit1 * 2)+1);
416#endif
417
418#if 0
419 ratio = ((long) lenght - (long) lzlenght) * 100 / ((long) lenght);
420 printf("Done!\n\nInput/Output ratio: %i/%i bytes (saved %ld%%)\n",
421 lenght, lzlenght, ratio);
422
423 /* Ok, let's now create the asm file */
424 /* the unpack routine is placed before the place where the unpacked code is said to be,
425 * according to the elf header (is it clean ? mmm, I guess not...).
426 */
427 buffer-=74;
428 starting_offset=*(unsigned long *)((char *)buffer+24);
429 memory=*(unsigned long *)((char *)buffer+64);
430 new_offset=starting_offset-lzlenght-74;
431 new_offset&=~4095;
432 new_offset+=74;
433 memory+=starting_offset - new_offset+4095;
434 memory&=~4095;
435
436 if (!(out=fopen("624.a.out.asm.816HDq", "wb"))) {
437 perror("624.a.out.asm.816HDq");
438 return ERROR;
439 }
440 fprintf(out, "BITS 32\n"
441 "org 0x%lx\n"
442 "%%define decompress_to 0x%lx\n"
443 "%%define data_length %d\n"
444 "%%define llstuff %d\n"
445 "%%define hl1stuff %d\n"
446 "%%define hl2stuff %d\n"
447 "%%define hf2stuff %d\n",
448 new_offset, starting_offset, lzlenght, lenlimit-1, log2(hufflimit1)+1, log2(hufflimit2)+1, (hufflimit1 * 2)+1);
449 fprintf(out, "%s", unpacker);
450 fprintf(out, "incbin \"%s\";\n", destfile);
451 fclose(out);
452
453 /* ok, let's nasm it and tinlink it */
454 /* don't worry about all those sprintf in a fixed size buffer, overflow is not possible */
455 sprintf(tin, "nasm -f bin -o 624.a.out.compressed.0012Aq 624.a.out.asm.816HDq");
456 fprintf(stderr, "%s\n", tin);
457 system(tin);
458 sprintf(tin, "tinlink -o %s -c 624.a.out.compressed.0012Aq -m %ld -s %p", aoutfile, memory, (unsigned char *)new_offset);
459 fprintf(stderr, "%s\n", tin);
460 system(tin);
461 sprintf(tin, "rm 624.a.out.compressed.0012Aq 624.a.out.asm.816HDq %s", destfile);
462 fprintf(stderr, "%s\n", tin);
463 system(tin);
464 return OK;
465#endif
466}