Advertisement
dannye33

pkmncompress.c

Aug 5th, 2015
321
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 8.43 KB | None | 0 0
  1. /*
  2.  * Copyright © 2013 stag019 <stag019@gmail.com>
  3.  *
  4.  * Permission to use, copy, modify, and distribute this software for any
  5.  * purpose with or without fee is hereby granted, provided that the above
  6.  * copyright notice and this permission notice appear in all copies.
  7.  *
  8.  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  9.  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  10.  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  11.  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  12.  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  13.  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  14.  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  15.  */
  16.  
  17. // XXX Shit to do XXX
  18. // reorder curbit? it makes sense in its logical form but perhaps reordering it will make it faster
  19. // "Get the previous power of 2. Deriving the bitcount from that seems to be faster on average than using the lookup table." ~ implemented. check to see if speed boost is true of C
  20.  
  21. #include <stdlib.h>
  22. #include <stdio.h>
  23. #include <stdint.h>
  24. #include <string.h>
  25.  
  26. uint8_t *compressed;
  27. int xrows;
  28. int xwidth;
  29. int curbit;
  30. int curbyte;
  31.  
  32. void writebit(int bit)
  33. {
  34.     if(++curbit == 8)
  35.     {
  36.         curbyte++;
  37.         curbit = 0;
  38.     }
  39.     compressed[curbyte] |= bit << (7 - curbit);
  40. }
  41.  
  42. void method_1(uint8_t *RAM)
  43. {
  44.     int i;
  45.     int j;
  46.     int nibble_1;
  47.     int nibble_2;
  48.     int code_1;
  49.     int code_2;
  50.     int table;
  51.     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}};
  52.  
  53.     for(i = 0; i < xrows * xwidth * 8; i++)
  54.     {
  55.         j = i / xrows;
  56.         j += i % xrows * xwidth * 8;
  57.         if(!(i % xrows))
  58.         {
  59.             nibble_2 = 0;
  60.         }
  61.         nibble_1 = (RAM[j] >> 4) & 0x0F;
  62.         table = 0;
  63.         if(nibble_2 & 1)
  64.         {
  65.             table = 1;
  66.         }
  67.         code_1 = method_1[table][nibble_1];
  68.         nibble_2 = RAM[j] & 0x0F;
  69.         table = 0;
  70.         if(nibble_1 & 1)
  71.         {
  72.             table = 1;
  73.         }
  74.         code_2 = method_1[table][nibble_2];
  75.         RAM[j] = (code_1 << 4) | code_2;
  76.     }
  77. }
  78.  
  79. void RLE(int nums)
  80. {
  81.     int v;
  82.     int i;
  83.     int j;
  84.     int bitcount;
  85.     int number;
  86.  
  87.     bitcount = -1;
  88.     v = ++nums;
  89.         v++;
  90.         v |= v >> 1;
  91.         v |= v >> 2;
  92.         v |= v >> 4;
  93.         v |= v >> 8;
  94.         v |= v >> 16;
  95.         v -= v >> 1;
  96.         v--;
  97.  
  98.     number = nums - v;
  99.         while(v)
  100.     {
  101.             v >>= 1;
  102.             bitcount++;
  103.     }
  104.     for(j = 0; j < bitcount; j++)
  105.     {
  106.         writebit(1);
  107.     }
  108.     writebit(0);
  109.     for(j = bitcount; j >= 0; j--)
  110.     {
  111.         writebit((number >> j) & 1);
  112.     }
  113. }
  114.  
  115. /*void RLE(int nums)
  116. {
  117.     int search;
  118.     int i;
  119.     int j;
  120.     int bitcount;
  121.     int number;
  122.     static unsigned int RLE[0x10] = {0x0001, 0x0003, 0x0007, 0x000F, 0x001F, 0x003F, 0x007F, 0x00FF, 0x01FF, 0x03FF, 0x07FF, 0x0FFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF};
  123.  
  124.     bitcount = -1;
  125.     search = ++nums;
  126.     while(search > 0)
  127.     {
  128.         for(i = 0; i < 0xF; i++)
  129.         {
  130.             if(RLE[i] == search)
  131.             {
  132.                 bitcount = i;
  133.                 break;
  134.             }
  135.         }
  136.         if(bitcount != -1)
  137.         {
  138.             break;
  139.         }
  140.         search--;
  141.     }
  142.     number = nums - RLE[bitcount];
  143.     for(j = 0; j < bitcount; j++)
  144.     {
  145.         writebit(1);
  146.     }
  147.     writebit(0);
  148.     for(j = bitcount; j >= 0; j--)
  149.     {
  150.         writebit((number >> j) & 1);
  151.     }
  152. }*/
  153.  
  154. void data_packet(uint8_t *bitgroups, int bgi)
  155. {
  156.     int i;
  157.     for(i = 0; i < bgi; i++)
  158.     {
  159.         writebit((bitgroups[i] >> 1) & 1);
  160.         writebit(bitgroups[i] & 1);
  161.     }
  162. }
  163.  
  164. int interpret_compress(uint8_t *RAM_1, uint8_t *RAM_2, int interpretation, int switchram)
  165. {
  166.     uint8_t *_1_RAM;
  167.     uint8_t *_2_RAM;
  168.     int i;
  169.     int ram;
  170.     int type;
  171.     int nums;
  172.     uint8_t *bitgroups;
  173.     int byte;
  174.     int bit;
  175.     int bitgroup;
  176.     int bgi = 0;
  177.  
  178.     _1_RAM = malloc(xrows * xwidth * 8);
  179.     _2_RAM = malloc(xrows * xwidth * 8);
  180.     if(switchram)
  181.     {
  182.         memcpy(_1_RAM, RAM_2, xrows * xwidth * 8);
  183.         memcpy(_2_RAM, RAM_1, xrows * xwidth * 8);
  184.     }
  185.     else
  186.     {
  187.         memcpy(_1_RAM, RAM_1, xrows * xwidth * 8);
  188.         memcpy(_2_RAM, RAM_2, xrows * xwidth * 8);
  189.     }
  190.  
  191.     switch(interpretation)
  192.     {
  193.         case 1:
  194.             method_1(_1_RAM);
  195.             method_1(_2_RAM);
  196.         break;
  197.         case 2:
  198.         case 3:
  199.             for(i = 0; i < xrows * xwidth * 8; i++)
  200.             {
  201.                 _2_RAM[i] ^= _1_RAM[i];
  202.             }
  203.             method_1(_1_RAM);
  204.         break;
  205.     }
  206.     if(interpretation == 3)
  207.     {
  208.         method_1(_2_RAM);
  209.     }
  210.  
  211.     curbit = 7;
  212.     curbyte = 0;
  213.     compressed = (uint8_t*) calloc(0x312, 1);
  214.     compressed[0] = (xrows << 4) | xwidth;
  215.     writebit(switchram);
  216.  
  217.     bitgroups = malloc(0x620);
  218.     for(ram = 0; ram < 2; ram++)
  219.     {
  220.         type = 0;
  221.         nums = 0;
  222.         for(i = 0; i < xrows * xwidth * 32; i++)
  223.         {
  224.             byte = i / (xwidth * 32);
  225.             byte = byte * xwidth * 8 + i % (xwidth * 8);
  226.             bit = i / (xwidth * 8);
  227.             bit = (bit * 2) % 8;
  228.             if(ram)
  229.             {
  230.                 bitgroup = (_2_RAM[byte] >> (6 - bit)) & 3;
  231.             }
  232.             else
  233.             {
  234.                 bitgroup = (_1_RAM[byte] >> (6 - bit)) & 3;
  235.             }
  236.             if(!bitgroup)
  237.             {
  238.                 if(!type)
  239.                 {
  240.                     writebit(0);
  241.                 }
  242.                 else if(type == 1)
  243.                 {
  244.                     nums++;
  245.                 }
  246.                 else
  247.                 {
  248.                     data_packet(bitgroups, bgi);
  249.                     writebit(0);
  250.                     writebit(0);
  251.                 }
  252.                 type = 1;
  253.                 bgi = 0;
  254.             }
  255.             else
  256.             {
  257.                 if(!type)
  258.                 {
  259.                     writebit(1);
  260.                 }
  261.                 else if(type == 1)
  262.                 {
  263.                     RLE(nums);
  264.                 }
  265.                 type = -1;
  266.                 bitgroups[bgi++] = bitgroup;
  267.                 nums = 0;
  268.             }
  269.         }
  270.         if(type == 1)
  271.         {
  272.             RLE(nums);
  273.         }
  274.         else
  275.         {
  276.             data_packet(bitgroups, bgi);
  277.         }
  278.         if(!ram)
  279.         {
  280.             if(interpretation < 2)
  281.             {
  282.                 writebit(0);
  283.             }
  284.             else
  285.             {
  286.                 writebit(1);
  287.                 writebit(interpretation - 2);
  288.             }
  289.         }
  290.     }
  291.     free(bitgroups);
  292.     free(_1_RAM);
  293.     free(_2_RAM);
  294.     return (curbyte + 1) * 8 + curbit;
  295. }
  296.  
  297. int compress(uint8_t *data, int width, int height)
  298. {
  299.     uint8_t *RAM_1;
  300.     uint8_t *RAM_2;
  301.     int i;
  302.     int newsize;
  303.     int size = -1;
  304.     uint8_t *current = NULL;
  305.  
  306.     xrows = height;
  307.     xwidth = width;
  308.  
  309.     RAM_1 = malloc(xrows * xwidth * 8);
  310.     RAM_2 = malloc(xrows * xwidth * 8);
  311.  
  312.     for(i = 0; i < xrows * xwidth * 8; i++)
  313.     {
  314.         RAM_1[i] = data[(i << 1)];
  315.         RAM_2[i] = data[(i << 1) | 1];
  316.     }
  317.  
  318.     for(i = 0; i < 6; i++)
  319.     {
  320.         if(i == 1)
  321.         {
  322.             continue;
  323.         }
  324.         newsize = interpret_compress(RAM_1, RAM_2, i / 2 + 1, i % 2);
  325.         if(size == -1 || newsize < size)
  326.         {
  327.             if(current != NULL)
  328.             {
  329.                 free(current);
  330.             }
  331.             size = newsize;
  332.             current = malloc(size / 8);
  333.             memcpy(current, compressed, size / 8);
  334.             free(compressed);
  335.         }
  336.     }
  337.     size /= 8;
  338.     compressed = malloc(size);
  339.     memcpy(compressed, current, size);
  340.     free(current);
  341.  
  342.     free(RAM_1);
  343.     free(RAM_2);
  344.  
  345.     return size;
  346. }
  347.  
  348. #ifdef POKERED
  349.     uint8_t *transpose_tiles(uint8_t *contents, int tiles)
  350.     {
  351.         uint8_t *newcontents;
  352.         int i;
  353.         int total_size;
  354.         int newbyte;
  355.  
  356.         total_size = tiles * tiles * 0x10;
  357.         newcontents = malloc(total_size);
  358.         for(i = 0; i < total_size; i++)
  359.         {
  360.             newbyte = i / 0x10 * tiles * 0x10;
  361.             newbyte = newbyte % total_size + 0x10 * (newbyte / total_size) + i % 0x10;
  362.             newcontents[newbyte] = contents[i];
  363.         }
  364.  
  365.         free(contents);
  366.  
  367.         return newcontents;
  368.     }
  369. #endif
  370.  
  371. int main(int argc, char *argv[])
  372. {
  373.     FILE *f;
  374.     int fz;
  375.     int size;
  376.     uint8_t *contents;
  377.     int tiles;
  378.     int *chloc;
  379.     int i;
  380.  
  381.     if(argc == 1)
  382.     {
  383.         #ifdef POKERED
  384.             return EXIT_SUCCESS;
  385.             // eventually this will be unneccesary, but for now, the queue
  386.             // will give empty parameters and this can't let it fail
  387.         #else
  388.             fputs("Usage: pkmncompress infile.2bpp [outfile.pic]\n", stderr);
  389.             return EXIT_FAILURE;
  390.         #endif
  391.     }
  392.  
  393.     for(i = 1; i < argc; i++)
  394.     {
  395.         if(strlen(argv[i]) - (strrchr(argv[i], '.') - argv[i]) < 4)
  396.         {
  397.             fputs("Error: Input filename extension must be 3 or more characters.\n", stderr);
  398.             return EXIT_FAILURE;
  399.         }
  400.         f = fopen(argv[i], "rb");
  401.  
  402.         if(!f)
  403.         {
  404.             perror("Opening file failed");
  405.             return EXIT_FAILURE;
  406.         }
  407.  
  408.         fseek(f, 0, SEEK_END);
  409.         fz = ftell(f);
  410.         if(fz == 0x310)
  411.         {
  412.             tiles = 7;
  413.         }
  414.         else if(fz == 0x240)
  415.         {
  416.             tiles = 6;
  417.         }
  418.         else if(fz == 0x190)
  419.         {
  420.             tiles = 5;
  421.         }
  422.         else if(fz == 0x100)
  423.         {
  424.             tiles = 4;
  425.         }
  426.         else
  427.         {
  428.             fputs("Error: Wrong file size.\n", stderr);
  429.             return EXIT_FAILURE;
  430.         }
  431.  
  432.         contents = malloc(fz);
  433.         fseek(f, 0, SEEK_SET);
  434.         fread(contents, 1, fz, f);
  435.         fclose(f);
  436.  
  437.         #ifdef POKERED
  438.             contents = transpose_tiles(contents, tiles);
  439.         #endif
  440.  
  441.         size = compress(contents, tiles, tiles);
  442.  
  443.         free(contents);
  444.  
  445.         strcpy(strrchr(argv[i], '.') + 1, "pic");
  446.         f = fopen(argv[i], "wb");
  447.         fwrite(compressed, 1, size, f);
  448.         fclose(f);
  449.  
  450.         free(compressed);
  451.     }
  452.  
  453.     return EXIT_SUCCESS;
  454. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement