Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // Compresses a File
- // By Kevin Macey
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- #include "defines.h"
- #include "pack.h"
- int compress(UCHAR infile[MAX]); // , UCHAR outfile[MAX]);
- int unused_bytecodes(char filename[MAX],UINT *bytecodes);
- typedef struct
- {
- ULONG number;
- UINT repeat;
- UINT unused;
- } number;
- typedef struct
- {
- UINT unused;
- ULONG number;
- } writenum;
- MAIN;
- ARGCHECK(1);
- compress(argv[1]); //,argv[1]); //,"empty");
- RET;
- END;
- int compress(UCHAR infile[MAX])// , UCHAR outfile[MAX])
- {
- // FILE VARABLES
- INPUT_FILE;
- OUTPUT_FILE;
- FILE *output2;
- // VARABLES
- ULONG inbyte=0;
- ULONG insize=0;
- ULONG filesize=0;
- ULONG count=0;
- number* list = malloc(65536 * sizeof(number));
- number* list2 = malloc(65535 * sizeof(number));
- writenum* out = malloc(65536 * sizeof(writenum));
- ULONG count2=0;
- ULONG pos=0;
- ULONG listpos=0;
- UINT done=0;
- // UINT intcodes=0;
- UINT outint=0;
- UINT unused[65536];
- UINT unused_total=0;
- ULONG position=0;
- UINT records;
- UCHAR outfile2[MAX];
- UCHAR outfile[MAX];
- UCHAR final[MAX];
- UCHAR lostinbytes[3];
- UINT lostinbytes_count = 0;
- strcpy(outfile2,"temp");
- strcpy(outfile,"temp2");
- strcpy(final,infile);
- strcat(final,".comp");
- // OPEN FILES
- FOI(infile);
- FOO(outfile);
- output2=fopen(outfile2,"wb");
- FILESIZE;
- insize=filesize;
- // change - added unused total
- // get all unused int codes
- unused_total=unused_bytecodes(infile, unused);
- // printf("%d\n",unused_total);
- // THIS IS A SPACE IMPROVEMENT BUT IT SLOWS THE PROGRAM DOWN CONSIDERABLY
- // FIND ONE UNUSED BYTECODE TO STORE 0 IN 1 BYTE
- // ADD FIND REOCCURING 0's SEPERATLY
- // STORE IN UNUSED BYTECODE
- // Find all reoccuring longs
- while ( (position < filesize / 4) && (listpos < 0x10000) ) //! feof(input) )
- {
- inbyte=0;
- // READ AN INT INTO BUFFER
- fread(&inbyte,1,4,input);
- done = 0;
- pos=0;
- // Find out if it is in the list already
- while ( ( pos < listpos ) && ( ! done ) )
- {
- if ( inbyte == list[pos].number )
- {
- //xfxprintf("%d Repeats %d times\n", inbyte, list[pos].repeat);
- list[pos].repeat++;
- // set byte to unused bytecode
- done=1;
- }
- pos++;
- }
- // if not found in list
- if ( ! done )
- {
- if (listpos < 0x10000)
- {
- // printf("Added: %d\n", inbyte);
- list[listpos].number = inbyte;
- list[listpos].repeat = 0;
- list[listpos].repeat++;
- // add to list
- listpos++;
- }
- }
- position++;
- END;
- lostinbytes_count = (filesize - (filesize / 4) * 4);
- if (lostinbytes_count > 0)
- {
- fseek(input, (filesize / 4) * 4, SEEK_SET);
- fread(lostinbytes, 1, lostinbytes_count, input);
- }
- // maybe sort numbers that reoccur more as a priority
- // if need to do it - sort here
- /*
- pos=unused_total;
- count=0;
- count2=0;
- // numsort
- while ( ( count < unused_total ) && ( count < listpos ) )
- {
- pos=unused_total;
- while ( ( count2 < unused_total ) && ( count2 < listpos ) )
- {
- if ( list[count].repeat > list[count2].repeat )
- {
- pos--;
- }
- count2++;
- }
- // list2[pos].number=0;
- // list2[pos].repeat=0;
- // list2[pos].unused=0;
- printf("Moving %d to position %d\n", list[count].number, pos);
- list2[pos].number=list[count].number;
- list2[pos].repeat=list[count].repeat;
- list2[pos].unused=0;
- count++;
- }
- // print table
- count=0;
- while ( count < unused_total )
- {
- if ( list[count].repeat > 1 )
- {
- printf("%d %d\n",list2[count].repeat, list2[count].number);
- }
- count++;
- }*/
- /*
- RESET;
- // frees unused bytecodes stort
- while ( count < unused_total )
- {
- while ( ! feof(input) )
- {
- fread(&inint,1,2,input);
- // compare int to two int in unused total
- }
- RESET;
- count++;
- }
- */
- // set unused into list, where repeat >= 5
- count = 0;
- pos = 0;
- while ( count < unused_total && pos < listpos)
- {
- if (list[pos].repeat >= 5)
- {
- list[pos].unused = unused[count];
- count++;
- }
- pos++;
- }
- // If unused runs out send error message
- if ( count == unused_total && pos < listpos)
- {
- printf("Unused Varables have run out\n");
- // set listpos to pos to mach unused ints count
- listpos = pos;
- }
- RESET;
- position = 0;
- while ( position < filesize / 4 )
- {
- fread(&inbyte,1,4,input);
- count=0;done=0;
- while ( ( count < listpos ) && ( ! done ) )
- {
- // if == repeat > amount
- if ( ( list[count].repeat >= 5 ) && ( list[count].number == inbyte ) )
- {
- // switch with unused bytecode
- outint=list[count].unused;
- done=1;
- }
- count++;
- }
- if ( done )
- {
- // write two bytes
- fwrite(&outint,1,2,output);
- }
- else
- {
- // write 4 bytes
- fwrite(&inbyte,1,4,output);
- }
- position++;
- END;
- // write last 1-3 bytes to file (lost at the end of file because of reading each 4 bytes)
- if (lostinbytes_count > 0)
- fwrite(lostinbytes,1,lostinbytes_count,output);
- count = 0;
- records = 0;
- while ( count < listpos )
- {
- if ( list[count].repeat >= 5 )
- {
- //printf("%d repeated %d times\n",list[count].number, list[count].repeat);
- filesize=filesize - ( list[count].repeat * 2 - 6) ;
- out[records].unused = list[count].unused;
- out[records].number = list[count].number;
- fwrite(&(out[records].unused), 1,2, output2);
- fwrite(&(out[records].number), 1,4, output2);
- records++;
- }
- count++;
- }
- //fwrite(out,sizeof(writenum),records,output2);
- // printf("\n\nOriginal Size: %d\nOutput Size: %d\n", insize, filesize);
- CLOSE(input);
- CLOSE(output);
- CLOSE(output2);
- // Pack to outputs
- pack(outfile,outfile2,final);
- free(list);
- free(out);
- RET;
- END;
- // FIND ALL UNUSED BYTECODES(INTS) IN A FILE
- int unused_bytecodes(char filename[MAX], UINT *unused)
- {
- INPUT_FILE;
- UINT inbyte;
- UINT intcode[65536];
- UINT d=0;
- UINT count=0;
- UINT i;
- ULONG pos = 0;
- ULONG filesize = 0;
- // initilyzing count
- for (i = 0; i < 65536; i++)
- intcode[i] = 0;
- input=fopen(filename,"rb");
- FILESIZE;
- FILELOOP_FILESIZE_INTS;
- inbyte = 0;
- READ_INT;
- intcode[inbyte] = 1;
- pos++;
- END;
- CLOSE(input);
- while ( d < 65536 )
- {
- if ( intcode[d] == 0 )
- {
- unused[count] = d;
- count++;
- }
- d++;
- }
- unused[count] = 0;
- return (count);
- END;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement