Advertisement
image28

Long Palette Based Compression

May 7th, 2016
156
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 6.32 KB | None | 0 0
  1.  // Compresses a File
  2. // By Kevin Macey
  3.  
  4. #include <stdio.h>
  5. #include <string.h>
  6. #include <stdlib.h>
  7.  
  8. #include "defines.h"
  9. #include "pack.h"
  10.  
  11. int compress(UCHAR infile[MAX]); // , UCHAR outfile[MAX]);
  12. int unused_bytecodes(char filename[MAX],UINT *bytecodes);
  13.  
  14. typedef struct
  15. {
  16.     ULONG number;
  17.     UINT repeat;
  18.     UINT unused;
  19. } number;
  20.  
  21. typedef struct
  22. {
  23.     UINT unused;
  24.     ULONG number;
  25. } writenum;
  26.  
  27. MAIN;
  28.     ARGCHECK(1);
  29.  
  30.     compress(argv[1]); //,argv[1]); //,"empty");
  31.  
  32.     RET;
  33. END;
  34.  
  35. int compress(UCHAR infile[MAX])// , UCHAR outfile[MAX])
  36. {
  37.  
  38.     // FILE VARABLES
  39.     INPUT_FILE;
  40.     OUTPUT_FILE;
  41.     FILE *output2;
  42.  
  43.     // VARABLES
  44.     ULONG inbyte=0;
  45.     ULONG insize=0;
  46.     ULONG filesize=0;
  47.     ULONG count=0;
  48.     number* list = malloc(65536 * sizeof(number));
  49.     number* list2 = malloc(65535 * sizeof(number));
  50.     writenum* out = malloc(65536 * sizeof(writenum));
  51.  
  52.     ULONG count2=0;
  53.     ULONG pos=0;
  54.     ULONG listpos=0;
  55.     UINT done=0;
  56. //  UINT intcodes=0;
  57.     UINT outint=0;
  58.     UINT unused[65536];
  59.     UINT unused_total=0;
  60.  
  61.     ULONG position=0;
  62.  
  63.     UINT records;
  64.  
  65.     UCHAR outfile2[MAX];
  66.     UCHAR outfile[MAX];
  67.  
  68.     UCHAR final[MAX];
  69.  
  70.     UCHAR lostinbytes[3];
  71.     UINT lostinbytes_count = 0;
  72.  
  73.     strcpy(outfile2,"temp");
  74.     strcpy(outfile,"temp2");
  75.    
  76.     strcpy(final,infile);
  77.     strcat(final,".comp");
  78.  
  79.     // OPEN FILES
  80.     FOI(infile);
  81.     FOO(outfile);
  82.     output2=fopen(outfile2,"wb");
  83.  
  84.     FILESIZE;
  85.  
  86.     insize=filesize;
  87.  
  88.  
  89.     // change - added unused total
  90.  
  91.     // get all unused int codes
  92.     unused_total=unused_bytecodes(infile, unused);
  93.  
  94. //  printf("%d\n",unused_total);
  95.  
  96.  
  97. // THIS IS A SPACE IMPROVEMENT BUT IT SLOWS THE PROGRAM DOWN CONSIDERABLY
  98.     // FIND ONE UNUSED BYTECODE TO STORE 0 IN 1 BYTE
  99.  
  100.     // ADD FIND REOCCURING 0's SEPERATLY
  101.     // STORE IN UNUSED BYTECODE
  102.  
  103.     // Find all reoccuring longs
  104.     while ( (position < filesize / 4) && (listpos < 0x10000) ) //! feof(input) )
  105.     {
  106.         inbyte=0;
  107.         // READ AN INT INTO BUFFER
  108.         fread(&inbyte,1,4,input);
  109.  
  110.         done = 0;
  111.         pos=0;
  112.  
  113.         // Find out if it is in the list already
  114.         while ( ( pos < listpos ) && ( ! done ) )
  115.         {
  116.             if ( inbyte == list[pos].number )
  117.             {
  118.                 //xfxprintf("%d Repeats %d times\n", inbyte, list[pos].repeat);
  119.                 list[pos].repeat++;
  120.                 // set byte to unused bytecode
  121.                 done=1;
  122.             }
  123.             pos++;
  124.         }
  125.  
  126.         // if not found in list
  127.         if ( ! done )
  128.         {
  129.             if (listpos < 0x10000)
  130.             {
  131.             //  printf("Added: %d\n", inbyte);
  132.                 list[listpos].number = inbyte;
  133.                 list[listpos].repeat = 0;
  134.                 list[listpos].repeat++;
  135.  
  136.                 // add to list
  137.                 listpos++;
  138.             }
  139.         }
  140.  
  141.         position++;
  142.  
  143.     END;
  144.  
  145.     lostinbytes_count = (filesize - (filesize / 4) * 4);
  146.     if (lostinbytes_count > 0)
  147.     {
  148.         fseek(input, (filesize / 4) * 4, SEEK_SET);
  149.         fread(lostinbytes, 1, lostinbytes_count, input);
  150.     }
  151.  
  152.     // maybe sort numbers that reoccur more as a priority
  153.     // if need to do it - sort here
  154. /*
  155.     pos=unused_total;
  156.     count=0;
  157.     count2=0;
  158.  
  159.     // numsort
  160.     while ( ( count < unused_total ) && ( count < listpos ) )
  161.     {
  162.    
  163.         pos=unused_total;
  164.  
  165.         while ( ( count2 < unused_total )  && ( count2 < listpos ) )
  166.         {
  167.             if ( list[count].repeat > list[count2].repeat )
  168.             {
  169.                 pos--;
  170.             }
  171.  
  172.             count2++;
  173.         }
  174.  
  175.     //  list2[pos].number=0;
  176.     //  list2[pos].repeat=0;
  177.     //  list2[pos].unused=0;
  178.  
  179.  
  180.         printf("Moving %d to position %d\n", list[count].number, pos);
  181.         list2[pos].number=list[count].number;
  182.         list2[pos].repeat=list[count].repeat;
  183.         list2[pos].unused=0;
  184.  
  185.         count++;
  186.     }
  187.  
  188.     // print table
  189.  
  190.     count=0;
  191.  
  192.     while ( count < unused_total )
  193.     {
  194.         if ( list[count].repeat > 1 )
  195.         {
  196.             printf("%d %d\n",list2[count].repeat, list2[count].number);
  197.         }
  198.         count++;
  199.     }*/
  200. /*
  201.     RESET;
  202.  
  203.     // frees unused bytecodes stort
  204.     while ( count < unused_total )
  205.     {
  206.         while ( ! feof(input) )
  207.         {
  208.             fread(&inint,1,2,input);
  209.  
  210.             // compare int to two int in unused total
  211.         }
  212.  
  213.         RESET;
  214.  
  215.         count++;
  216.     }
  217.  
  218. */
  219.     // set unused into list, where repeat >= 5
  220.     count = 0;
  221.     pos = 0;
  222.     while ( count < unused_total && pos < listpos)
  223.     {
  224.         if (list[pos].repeat >= 5)
  225.         {
  226.             list[pos].unused = unused[count];
  227.             count++;
  228.         }
  229.         pos++;
  230.     }
  231.  
  232.     // If unused runs out send error message
  233.     if ( count == unused_total && pos < listpos)
  234.     {
  235.         printf("Unused Varables have run out\n");
  236.         // set listpos to pos to mach unused ints count
  237.         listpos = pos;
  238.     }
  239.  
  240.     RESET;
  241.  
  242.     position = 0;
  243.     while ( position < filesize / 4 )
  244.     {
  245.         fread(&inbyte,1,4,input);
  246.  
  247.         count=0;done=0;
  248.  
  249.         while ( ( count < listpos ) && ( ! done ) )
  250.         {
  251.             // if == repeat > amount
  252.             if ( ( list[count].repeat >= 5 ) && ( list[count].number == inbyte ) )
  253.             {
  254.                 // switch with unused bytecode
  255.                 outint=list[count].unused;
  256.                 done=1;
  257.  
  258.             }
  259.  
  260.             count++;
  261.  
  262.         }
  263.  
  264.         if ( done )
  265.         {
  266.             // write two bytes
  267.             fwrite(&outint,1,2,output);
  268.         }
  269.         else
  270.         {
  271.             // write 4 bytes
  272.             fwrite(&inbyte,1,4,output);
  273.         }
  274.  
  275.         position++;
  276.  
  277.     END;
  278.  
  279.     // write last 1-3 bytes to file (lost at the end of file because of reading each 4 bytes)
  280.     if (lostinbytes_count > 0)
  281.         fwrite(lostinbytes,1,lostinbytes_count,output);
  282.  
  283.     count = 0;
  284.  
  285.     records = 0;
  286.     while ( count < listpos )
  287.     {
  288.         if ( list[count].repeat >= 5 )
  289.         {
  290.             //printf("%d repeated %d times\n",list[count].number, list[count].repeat);
  291.  
  292.             filesize=filesize - ( list[count].repeat * 2 - 6) ;
  293.  
  294.             out[records].unused = list[count].unused;
  295.             out[records].number = list[count].number;
  296.  
  297.             fwrite(&(out[records].unused), 1,2, output2);
  298.             fwrite(&(out[records].number), 1,4, output2);
  299.  
  300.             records++;
  301.         }
  302.  
  303.         count++;
  304.     }
  305.  
  306.     //fwrite(out,sizeof(writenum),records,output2);
  307.  
  308. //  printf("\n\nOriginal Size: %d\nOutput Size: %d\n", insize, filesize);
  309.  
  310.     CLOSE(input);
  311.     CLOSE(output);
  312.     CLOSE(output2);
  313.  
  314.     // Pack to outputs
  315.     pack(outfile,outfile2,final);
  316.  
  317.     free(list);
  318.     free(out);
  319.  
  320.     RET;
  321.  
  322. END;
  323.  
  324.  
  325. // FIND ALL UNUSED BYTECODES(INTS) IN A FILE
  326. int unused_bytecodes(char filename[MAX], UINT *unused)
  327. {
  328.     INPUT_FILE;
  329.     UINT inbyte;
  330.     UINT intcode[65536];
  331.     UINT d=0;
  332.     UINT count=0;
  333.     UINT i;
  334.     ULONG pos = 0;
  335.     ULONG filesize = 0;
  336.  
  337.     // initilyzing count
  338.     for (i = 0; i < 65536; i++)
  339.         intcode[i] = 0;
  340.  
  341.     input=fopen(filename,"rb");
  342.     FILESIZE;
  343.  
  344.     FILELOOP_FILESIZE_INTS;
  345.  
  346.         inbyte = 0;
  347.         READ_INT;
  348.  
  349.         intcode[inbyte] = 1;
  350.  
  351.         pos++;
  352.     END;
  353.  
  354.     CLOSE(input);
  355.  
  356.     while ( d < 65536 )
  357.     {
  358.         if ( intcode[d] == 0 )
  359.         {
  360.             unused[count] = d;
  361.             count++;
  362.         }
  363.         d++;
  364.     }
  365.     unused[count] = 0;
  366.  
  367.     return (count);
  368. END;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement