Guest User

pkmncompress.c

a guest
Jul 25th, 2012
358
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