Advertisement
Guest User

pkmncompress.c

a guest
Sep 24th, 2013
588
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <stdint.h>
  4. #include <string.h>
  5.  
  6. uint8_t *compressed;
  7. int xrows;
  8. int xwidth;
  9. int curbit;
  10. int curbyte;
  11.  
  12. void writebit(int bit)
  13. {
  14.     if(++curbit == 8)
  15.     {
  16.         curbyte++;
  17.         curbit = 0;
  18.     }
  19.     compressed[curbyte] |= bit << (7 - curbit);
  20. }
  21.  
  22. void method_1(uint8_t *RAM)
  23. {
  24.     int i;
  25.     int j;
  26.     int nibble_1;
  27.     int nibble_2;
  28.     int code_1;
  29.     int code_2;
  30.     int table;
  31.     static int method_1[2][0x10] = {{0x0, 0x1, 0x3, 0x2, 0x6, 0x7, 0x5, 0x4, 0xC, 0xD, 0xF, 0xE, 0xA, 0xB, 0x9, 0x8}, {0x8, 0x9, 0xB, 0xA, 0xE, 0xF, 0xD, 0xC, 0x4, 0x5, 0x7, 0x6, 0x2, 0x3, 0x1, 0x0}};
  32.  
  33.     for(i = 0; i < xrows * xwidth * 8; i++)
  34.     {
  35.         j = i / xrows;
  36.         j += i % xrows * xwidth * 8;
  37.         if(!(i % xrows))
  38.         {
  39.             nibble_2 = 0;
  40.         }
  41.         nibble_1 = (RAM[j] >> 4) & 0x0F;
  42.         table = 0;
  43.         if(nibble_2 & 1)
  44.         {
  45.             table = 1;
  46.         }
  47.         code_1 = method_1[table][nibble_1];
  48.         nibble_2 = RAM[j] & 0x0F;
  49.         table = 0;
  50.         if(nibble_1 & 1)
  51.         {
  52.             table = 1;
  53.         }
  54.         code_2 = method_1[table][nibble_2];
  55.         RAM[j] = (code_1 << 4) | code_2;
  56.     }
  57. }
  58.  
  59. void RLE(int nums)
  60. {
  61.     int search;
  62.     int i;
  63.     int j;
  64.     int bitcount;
  65.     int number;
  66.     static unsigned int RLE[0x10] = {0x0001, 0x0003, 0x0007, 0x000F, 0x001F, 0x003F, 0x007F, 0x00FF, 0x01FF, 0x03FF, 0x07FF, 0x0FFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF};
  67.  
  68.     bitcount = -1;
  69.     search = ++nums;
  70.     while(search > 0)
  71.     {
  72.         for(i = 0; i < 0xF; i++)
  73.         {
  74.             if(RLE[i] == search)
  75.             {
  76.                 bitcount = i;
  77.                 break;
  78.             }
  79.         }
  80.         if(bitcount != -1)
  81.         {
  82.             break;
  83.         }
  84.         search--;
  85.     }
  86.     number = nums - RLE[bitcount];
  87.     for(j = 0; j < bitcount; j++)
  88.     {
  89.         writebit(1);
  90.     }
  91.     writebit(0);
  92.     for(j = bitcount; j >= 0; j--)
  93.     {
  94.         writebit((number >> j) & 1);
  95.     }
  96. }
  97.  
  98. void data_packet(uint8_t *bitgroups, int bgi)
  99. {
  100.     int i;
  101.     for(i = 0; i < bgi; i++)
  102.     {
  103.         writebit((bitgroups[i] >> 1) & 1);
  104.         writebit(bitgroups[i] & 1);
  105.     }
  106. }
  107.  
  108. int interpret_compress(uint8_t *RAM_1, uint8_t *RAM_2, int interpretation, int switchram)
  109. {
  110.     uint8_t *_1_RAM;
  111.     uint8_t *_2_RAM;
  112.     int i;
  113.     int ram;
  114.     int type;
  115.     int nums;
  116.     uint8_t *bitgroups;
  117.     int byte;
  118.     int bit;
  119.     int bitgroup;
  120.     int bgi = 0;
  121.  
  122.     _1_RAM = (uint8_t*) calloc(0x188, 1);
  123.     _2_RAM = (uint8_t*) calloc(0x188, 1);
  124.     if(switchram)
  125.     {
  126.         memcpy(_1_RAM, RAM_2, 0x188);
  127.         memcpy(_2_RAM, RAM_1, 0x188);
  128.     }
  129.     else
  130.     {
  131.         memcpy(_1_RAM, RAM_1, 0x188);
  132.         memcpy(_2_RAM, RAM_2, 0x188);
  133.     }
  134.  
  135.     switch(interpretation)
  136.     {
  137.         case 1:
  138.             method_1(_1_RAM);
  139.             method_1(_2_RAM);
  140.         break;
  141.         case 2:
  142.         case 3:
  143.             for(i = 0; i < xrows * xwidth * 8; i++)
  144.             {
  145.                 _2_RAM[i] ^= _1_RAM[i];
  146.             }
  147.             method_1(_1_RAM);
  148.         break;
  149.     }
  150.     if(interpretation == 3)
  151.     {
  152.         method_1(_2_RAM);
  153.     }
  154.  
  155.     curbit = 7;
  156.     curbyte = 0;
  157.     compressed = (uint8_t*) calloc(0x310, 1);
  158.     compressed[0] = (xrows << 4) | xwidth;
  159.     writebit(switchram);
  160.  
  161.     for(ram = 0; ram < 2; ram++)
  162.     {
  163.         type = 0;
  164.         nums = 0;
  165.         bitgroups = (uint8_t*) calloc(0x1000, 1);
  166.         for(i = 0; i < xrows * xwidth * 32; i++)
  167.         {
  168.             byte = i / (xwidth * 32);
  169.             byte = byte * xwidth * 8 + i % (xwidth * 8);
  170.             bit = i / (xwidth * 8);
  171.             bit = (bit * 2) % 8;
  172.             if(ram)
  173.             {
  174.                 bitgroup = (_2_RAM[byte] >> (6 - bit)) & 3;
  175.             }
  176.             else
  177.             {
  178.                 bitgroup = (_1_RAM[byte] >> (6 - bit)) & 3;
  179.             }
  180.             if(!bitgroup)
  181.             {
  182.                 if(!type)
  183.                 {
  184.                     writebit(0);
  185.                 }
  186.                 else if(type == 1)
  187.                 {
  188.                     nums++;
  189.                 }
  190.                 else
  191.                 {
  192.                     data_packet(bitgroups, bgi);
  193.                     writebit(0);
  194.                     writebit(0);
  195.                 }
  196.                 type = 1;
  197.                 free(bitgroups);
  198.                 bitgroups = (uint8_t*) calloc(0x1000, 1);
  199.                 bgi = 0;
  200.             }
  201.             else
  202.             {
  203.                 if(!type)
  204.                 {
  205.                     writebit(1);
  206.                 }
  207.                 else if(type == 1)
  208.                 {
  209.                     RLE(nums);
  210.                 }
  211.                 type = -1;
  212.                 bitgroups[bgi++] = bitgroup;
  213.                 nums = 0;
  214.             }
  215.         }
  216.         if(type == 1)
  217.         {
  218.             RLE(nums);
  219.         }
  220.         else
  221.         {
  222.             data_packet(bitgroups, bgi);
  223.         }
  224.         if(!ram)
  225.         {
  226.             if(interpretation < 2)
  227.             {
  228.                 writebit(0);
  229.             }
  230.             else
  231.             {
  232.                 writebit(1);
  233.                 writebit(interpretation - 2);
  234.             }
  235.         }
  236.     }
  237.     free(bitgroups);
  238.     free(_1_RAM);
  239.     free(_2_RAM);
  240.     return curbyte + 1;
  241. }
  242.  
  243. int compress(uint8_t *data, int width, int height)
  244. {
  245.     uint8_t *RAM_1;
  246.     uint8_t *RAM_2;
  247.     int i;
  248.     int newsize;
  249.     int size = -1;
  250.     uint8_t *current = NULL;
  251.  
  252.     xrows = height;
  253.     xwidth = width;
  254.  
  255.     RAM_1 = (uint8_t*) calloc(0x188, 1);
  256.     RAM_2 = (uint8_t*) calloc(0x188, 1);
  257.  
  258.     for(i = 0; i < xrows * xwidth * 8; i++)
  259.     {
  260.         RAM_1[i] = data[(i << 1)];
  261.         RAM_2[i] = data[(i << 1) | 1];
  262.     }
  263.  
  264.     for(i = 0; i < 6; i++)
  265.     {
  266.         newsize = interpret_compress(RAM_1, RAM_2, i / 2 + 1, i % 2);
  267.         if(size == -1 || newsize < size)
  268.         {
  269.             if(current != NULL)
  270.             {
  271.                 free(current);
  272.             }
  273.             current = (uint8_t*) calloc(0x310, 1);
  274.             memcpy(current, compressed, newsize);
  275.             free(compressed);
  276.             size = newsize;
  277.         }
  278.     }
  279.     compressed = (uint8_t*) calloc(0x310, 1);
  280.     memcpy(compressed, current, size);
  281.     free(current);
  282.  
  283.     free(RAM_1);
  284.     free(RAM_2);
  285.  
  286.     return size;
  287. }
  288.  
  289. int main(int argc, char *argv[])
  290. {
  291.     FILE *f;
  292.     int fz;
  293.     int size;
  294.     uint8_t *contents;
  295.     int tiles;
  296.  
  297.     if(argc < 3)
  298.     {
  299.         printf("Usage: pkmncompress infile.2bpp outfile.bin\n");
  300.         /*fputs("Usage: pkmncompress infile.2bpp outfile.bin\n", stderr);*/
  301.         return EXIT_FAILURE;
  302.     }
  303.  
  304.     f = fopen(argv[1], "rb");
  305.  
  306.     if(!f)
  307.     {
  308.         perror("Opening file failed");
  309.         return EXIT_FAILURE;
  310.     }
  311.  
  312.     fseek(f, 0, SEEK_END);
  313.     fz = ftell(f);
  314.     if(fz == 0x310)
  315.     {
  316.         tiles = 7;
  317.     }
  318.     else if(fz == 0x240)
  319.     {
  320.         tiles = 6;
  321.     }
  322.     else if(fz == 0x190)
  323.     {
  324.         tiles = 5;
  325.     }
  326.     else if(fz == 0x100)
  327.     {
  328.         tiles = 4;
  329.     }
  330.     else
  331.     {
  332.         printf("Error: wrong file size.\n");
  333.         /*fputs("Error: wrong file size.\n", stderr);*/
  334.         return EXIT_FAILURE;
  335.     }
  336.  
  337.     contents = (uint8_t*) calloc(0x310, 1);
  338.     fseek(f, 0, SEEK_SET);
  339.     fread(contents, 1, fz, f);
  340.     fclose(f);
  341.  
  342.     size = compress(contents, tiles, tiles);
  343.  
  344.     free(contents);
  345.  
  346.     f = fopen(argv[2], "wb");
  347.     fwrite(compressed, 1, size, f);
  348.  
  349.     free(compressed);
  350.  
  351.     printf("Success! File size: %i bytes\n", size);
  352.  
  353.     return EXIT_SUCCESS;
  354. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement