Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- * Copyright © 2013 stag019 <stag019@gmail.com>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
- #include <stdlib.h>
- #include <stdio.h>
- #include <stdint.h>
- #include <string.h>
- uint8_t *compressed;
- int xrows;
- int xwidth;
- int curbit;
- int curbyte;
- void writebit(int bit)
- {
- if(++curbit == 8)
- {
- curbyte++;
- curbit = 0;
- }
- compressed[curbyte] |= bit << (7 - curbit);
- }
- void method_1(uint8_t *RAM)
- {
- int i;
- int j;
- int nibble_1;
- int nibble_2;
- int code_1;
- int code_2;
- int table;
- 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}};
- for(i = 0; i < xrows * xwidth * 8; i++)
- {
- j = i / xrows;
- j += i % xrows * xwidth * 8;
- if(!(i % xrows))
- {
- nibble_2 = 0;
- }
- nibble_1 = (RAM[j] >> 4) & 0x0F;
- table = 0;
- if(nibble_2 & 1)
- {
- table = 1;
- }
- code_1 = method_1[table][nibble_1];
- nibble_2 = RAM[j] & 0x0F;
- table = 0;
- if(nibble_1 & 1)
- {
- table = 1;
- }
- code_2 = method_1[table][nibble_2];
- RAM[j] = (code_1 << 4) | code_2;
- }
- }
- void RLE(int nums)
- {
- int search;
- int i;
- int j;
- int bitcount;
- int number;
- static unsigned int RLE[0x10] = {0x0001, 0x0003, 0x0007, 0x000F, 0x001F, 0x003F, 0x007F, 0x00FF, 0x01FF, 0x03FF, 0x07FF, 0x0FFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF};
- bitcount = -1;
- search = ++nums;
- while(search > 0)
- {
- for(i = 0; i < 0xF; i++)
- {
- if(RLE[i] == search)
- {
- bitcount = i;
- break;
- }
- }
- if(bitcount != -1)
- {
- break;
- }
- search--;
- }
- number = nums - RLE[bitcount];
- for(j = 0; j < bitcount; j++)
- {
- writebit(1);
- }
- writebit(0);
- for(j = bitcount; j >= 0; j--)
- {
- writebit((number >> j) & 1);
- }
- }
- void data_packet(uint8_t *bitgroups, int bgi)
- {
- int i;
- for(i = 0; i < bgi; i++)
- {
- writebit((bitgroups[i] >> 1) & 1);
- writebit(bitgroups[i] & 1);
- }
- }
- int interpret_compress(uint8_t *RAM_1, uint8_t *RAM_2, int interpretation, int switchram)
- {
- uint8_t *_1_RAM;
- uint8_t *_2_RAM;
- int i;
- int ram;
- int type;
- int nums;
- uint8_t *bitgroups;
- int byte;
- int bit;
- int bitgroup;
- int bgi = 0;
- _1_RAM = (uint8_t*) calloc(0x188, 1);
- _2_RAM = (uint8_t*) calloc(0x188, 1);
- if(switchram)
- {
- memcpy(_1_RAM, RAM_2, 0x188);
- memcpy(_2_RAM, RAM_1, 0x188);
- }
- else
- {
- memcpy(_1_RAM, RAM_1, 0x188);
- memcpy(_2_RAM, RAM_2, 0x188);
- }
- switch(interpretation)
- {
- case 1:
- method_1(_1_RAM);
- method_1(_2_RAM);
- break;
- case 2:
- case 3:
- for(i = 0; i < xrows * xwidth * 8; i++)
- {
- _2_RAM[i] ^= _1_RAM[i];
- }
- method_1(_1_RAM);
- break;
- }
- if(interpretation == 3)
- {
- method_1(_2_RAM);
- }
- curbit = 7;
- curbyte = 0;
- compressed = (uint8_t*) calloc(0x310, 1);
- compressed[0] = (xrows << 4) | xwidth;
- writebit(switchram);
- for(ram = 0; ram < 2; ram++)
- {
- type = 0;
- nums = 0;
- bitgroups = (uint8_t*) calloc(0x1000, 1);
- for(i = 0; i < xrows * xwidth * 32; i++)
- {
- byte = i / (xwidth * 32);
- byte = byte * xwidth * 8 + i % (xwidth * 8);
- bit = i / (xwidth * 8);
- bit = (bit * 2) % 8;
- if(ram)
- {
- bitgroup = (_2_RAM[byte] >> (6 - bit)) & 3;
- }
- else
- {
- bitgroup = (_1_RAM[byte] >> (6 - bit)) & 3;
- }
- if(!bitgroup)
- {
- if(!type)
- {
- writebit(0);
- }
- else if(type == 1)
- {
- nums++;
- }
- else
- {
- data_packet(bitgroups, bgi);
- writebit(0);
- writebit(0);
- }
- type = 1;
- free(bitgroups);
- bitgroups = (uint8_t*) calloc(0x1000, 1);
- bgi = 0;
- }
- else
- {
- if(!type)
- {
- writebit(1);
- }
- else if(type == 1)
- {
- RLE(nums);
- }
- type = -1;
- bitgroups[bgi++] = bitgroup;
- nums = 0;
- }
- }
- if(type == 1)
- {
- RLE(nums);
- }
- else
- {
- data_packet(bitgroups, bgi);
- }
- if(!ram)
- {
- if(interpretation < 2)
- {
- writebit(0);
- }
- else
- {
- writebit(1);
- writebit(interpretation - 2);
- }
- }
- }
- free(bitgroups);
- free(_1_RAM);
- free(_2_RAM);
- return curbyte + 1;
- }
- int compress(uint8_t *data, int width, int height)
- {
- uint8_t *RAM_1;
- uint8_t *RAM_2;
- int i;
- int newsize;
- int size = -1;
- uint8_t *current = NULL;
- xrows = height;
- xwidth = width;
- RAM_1 = (uint8_t*) calloc(0x188, 1);
- RAM_2 = (uint8_t*) calloc(0x188, 1);
- for(i = 0; i < xrows * xwidth * 8; i++)
- {
- RAM_1[i] = data[(i << 1)];
- RAM_2[i] = data[(i << 1) | 1];
- }
- for(i = 0; i < 6; i++)
- {
- newsize = interpret_compress(RAM_1, RAM_2, i / 2 + 1, i % 2);
- if(size == -1 || newsize < size)
- {
- if(current != NULL)
- {
- free(current);
- }
- current = (uint8_t*) calloc(0x310, 1);
- memcpy(current, compressed, newsize);
- free(compressed);
- size = newsize;
- }
- }
- compressed = (uint8_t*) calloc(0x310, 1);
- memcpy(compressed, current, size);
- free(current);
- free(RAM_1);
- free(RAM_2);
- return size;
- }
- int main(int argc, char *argv[])
- {
- FILE *f;
- int fz;
- int size;
- uint8_t *contents;
- int tiles;
- int *chloc;
- char outfile[256];
- if(argc < 2)
- {
- fputs("Usage: pkmncompress infile.2bpp [outfile.bin]\n", stderr);
- return EXIT_FAILURE;
- }
- if(argc == 2)
- {
- strcpy(outfile, argv[1]);
- if((chloc = (int *) strrchr(outfile, '.')) != NULL)
- {
- strcpy((char *) chloc, ".bin");
- }
- else
- {
- strcat(outfile, ".bin");
- }
- }
- else
- {
- strcpy(outfile, argv[2]);
- }
- f = fopen(argv[1], "rb");
- if(!f)
- {
- perror("Opening file failed");
- return EXIT_FAILURE;
- }
- fseek(f, 0, SEEK_END);
- fz = ftell(f);
- if(fz == 0x310)
- {
- tiles = 7;
- }
- else if(fz == 0x240)
- {
- tiles = 6;
- }
- else if(fz == 0x190)
- {
- tiles = 5;
- }
- else if(fz == 0x100)
- {
- tiles = 4;
- }
- else
- {
- fputs("Error: wrong file size.\n", stderr);
- return EXIT_FAILURE;
- }
- contents = (uint8_t*) calloc(0x310, 1);
- fseek(f, 0, SEEK_SET);
- fread(contents, 1, fz, f);
- fclose(f);
- size = compress(contents, tiles, tiles);
- free(contents);
- f = fopen(outfile, "wb");
- fwrite(compressed, 1, size, f);
- free(compressed);
- printf("Success! File size: %i bytes\n", size);
- return EXIT_SUCCESS;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement