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.
- */
- // XXX Shit to do XXX
- // reorder curbit? it makes sense in its logical form but perhaps reordering it will make it faster
- // "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
- #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 v;
- int i;
- int j;
- int bitcount;
- int number;
- bitcount = -1;
- v = ++nums;
- v++;
- v |= v >> 1;
- v |= v >> 2;
- v |= v >> 4;
- v |= v >> 8;
- v |= v >> 16;
- v -= v >> 1;
- v--;
- number = nums - v;
- while(v)
- {
- v >>= 1;
- bitcount++;
- }
- for(j = 0; j < bitcount; j++)
- {
- writebit(1);
- }
- writebit(0);
- for(j = bitcount; j >= 0; j--)
- {
- writebit((number >> j) & 1);
- }
- }
- /*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 = malloc(xrows * xwidth * 8);
- _2_RAM = malloc(xrows * xwidth * 8);
- if(switchram)
- {
- memcpy(_1_RAM, RAM_2, xrows * xwidth * 8);
- memcpy(_2_RAM, RAM_1, xrows * xwidth * 8);
- }
- else
- {
- memcpy(_1_RAM, RAM_1, xrows * xwidth * 8);
- memcpy(_2_RAM, RAM_2, xrows * xwidth * 8);
- }
- 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(0x312, 1);
- compressed[0] = (xrows << 4) | xwidth;
- writebit(switchram);
- bitgroups = malloc(0x620);
- for(ram = 0; ram < 2; ram++)
- {
- type = 0;
- nums = 0;
- 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;
- 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) * 8 + curbit;
- }
- 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 = malloc(xrows * xwidth * 8);
- RAM_2 = malloc(xrows * xwidth * 8);
- 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++)
- {
- if(i == 1)
- {
- continue;
- }
- newsize = interpret_compress(RAM_1, RAM_2, i / 2 + 1, i % 2);
- if(size == -1 || newsize < size)
- {
- if(current != NULL)
- {
- free(current);
- }
- size = newsize;
- current = malloc(size / 8);
- memcpy(current, compressed, size / 8);
- free(compressed);
- }
- }
- size /= 8;
- compressed = malloc(size);
- memcpy(compressed, current, size);
- free(current);
- free(RAM_1);
- free(RAM_2);
- return size;
- }
- #ifdef POKERED
- uint8_t *transpose_tiles(uint8_t *contents, int tiles)
- {
- uint8_t *newcontents;
- int i;
- int total_size;
- int newbyte;
- total_size = tiles * tiles * 0x10;
- newcontents = malloc(total_size);
- for(i = 0; i < total_size; i++)
- {
- newbyte = i / 0x10 * tiles * 0x10;
- newbyte = newbyte % total_size + 0x10 * (newbyte / total_size) + i % 0x10;
- newcontents[newbyte] = contents[i];
- }
- free(contents);
- return newcontents;
- }
- #endif
- int main(int argc, char *argv[])
- {
- FILE *f;
- int fz;
- int size;
- uint8_t *contents;
- int tiles;
- int *chloc;
- int i;
- if(argc == 1)
- {
- #ifdef POKERED
- return EXIT_SUCCESS;
- // eventually this will be unneccesary, but for now, the queue
- // will give empty parameters and this can't let it fail
- #else
- fputs("Usage: pkmncompress infile.2bpp [outfile.pic]\n", stderr);
- return EXIT_FAILURE;
- #endif
- }
- for(i = 1; i < argc; i++)
- {
- if(strlen(argv[i]) - (strrchr(argv[i], '.') - argv[i]) < 4)
- {
- fputs("Error: Input filename extension must be 3 or more characters.\n", stderr);
- return EXIT_FAILURE;
- }
- f = fopen(argv[i], "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 = malloc(fz);
- fseek(f, 0, SEEK_SET);
- fread(contents, 1, fz, f);
- fclose(f);
- #ifdef POKERED
- contents = transpose_tiles(contents, tiles);
- #endif
- size = compress(contents, tiles, tiles);
- free(contents);
- strcpy(strrchr(argv[i], '.') + 1, "pic");
- f = fopen(argv[i], "wb");
- fwrite(compressed, 1, size, f);
- fclose(f);
- free(compressed);
- }
- return EXIT_SUCCESS;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement