daily pastebin goal
15%
SHARE
TWEET

pkmncompress.c

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