diff options
| author | Root THC | 2026-02-24 12:42:47 +0000 |
|---|---|---|
| committer | Root THC | 2026-02-24 12:42:47 +0000 |
| commit | c9cbeced5b3f2bdd7407e29c0811e65954132540 (patch) | |
| tree | aefc355416b561111819de159ccbd86c3004cf88 /other/wrez/compressor.c | |
| parent | 073fe4bf9fca6bf40cef2886d75df832ef4b6fca (diff) | |
initial
Diffstat (limited to 'other/wrez/compressor.c')
| -rw-r--r-- | other/wrez/compressor.c | 466 |
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 | |||
| 28 | byte _buffer[MAXSIZE], lzbuffer[MAXSIZE]; | ||
| 29 | byte * buffer=0; | ||
| 30 | word lenght=0, lzlenght=0, hufflimit1=0, hufflimit2=0, lenlimit=0, decodelenght=0; | ||
| 31 | int maxhuffman=0, dummy=0; | ||
| 32 | int bitpos=0; | ||
| 33 | |||
| 34 | char *rotorchar = "-/|\\"; | ||
| 35 | |||
| 36 | char *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 | |||
| 41 | char *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 | |||
| 59 | void 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 | |||
| 90 | void 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 | |||
| 107 | void 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 | |||
| 142 | word 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 | |||
| 171 | void 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 | |||
| 249 | void 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 | |||
| 310 | int | ||
| 311 | main (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 | } | ||
