Difference between revisions of "User:Remark/Icon2ppm.c"
Jump to navigation
Jump to search
(I'll just leave this here..) |
(No difference)
|
Revision as of 22:31, 27 April 2009
// DSi icon2ppm - #dsidev // written by remark // thanks to loopy_, bLASTY // Copyright 2007,2008 Segher Boessenkool <segher@kernel.crashing.org> // Licensed under the terms of the GNU GPL, version 2 // http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt #include <stdio.h> #include <unistd.h> typedef unsigned long u32; typedef unsigned short u16; typedef unsigned char u8; u16 be16(const u8 *p) { return (p[0] << 8) | p[1]; } u32 be32(const u8 *p) { return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]; } #define BNR_VER 0x0301 #define FLAG_FLIPV 0x8000 #define FLAG_FLIPH 0x4000 typedef struct { u16 version; u16 crcs[4]; u8 padding[0x16]; u8 bitmap[0x200]; u16 palette[0x10]; u8 title_jap[0x100]; u8 title_eng[0x100]; u8 title_fr[0x100]; u8 title_ger[0x100]; u8 title_ita[0x100]; u8 title_spa[0x100]; u8 title_unk[0x100]; u8 title_unk2[0x100]; u8 padding2[0x800]; u8 bitmaps[8][0x200]; u16 palettes[8][0x10]; u16 sequence[0x40]; } bannerstruct; int flength(FILE *f) { int pos,end; pos = ftell (f); fseek (f, 0, SEEK_END); end = ftell (f); fseek (f, pos, SEEK_SET); return end; } void do_bitmap(u8* bitmap, u16* palette, char* fname) { FILE *fp = fopen(fname, "wb"); if (fp == NULL) { fprintf(stderr, "file cannot be opened: %s\n", fname); exit(1); } fprintf(fp, "P6 %d %d 255\n", 32, 32); // fix 8x8 tiling u8 tilebuf[0x204]; int x,y,z; for(x=0; x<4; x++) { for(y=0; y<8; y++) { for(z=0; z<8; z++) { memcpy(tilebuf+(x*128)+(16*y)+(4*z), bitmap+(x*128)+(32*z)+(4*y), 4); } } } // convert to rgb888 int i,j; u8 pixeldata[32*32][3]; for(i=0; i<0x200; i++) { u8 off = tilebuf[i]; int offs[2]; offs[0] = off&0x0F; offs[1] = (off&0xF0)>>4; u16 colors[2]; colors[0] = *(palette+offs[0]); colors[1] = *(palette+offs[1]); for(j=0; j<2; j++) { u8 r = (colors[j] ) & 0x1f; u8 g = (colors[j] >> 5) & 0x1f; u8 b = (colors[j] >> 10) & 0x1f; pixeldata[i*2+j][0] = (r << 3); pixeldata[i*2+j][1] = (g << 3); pixeldata[i*2+j][2] = (b << 3); } } if(fwrite(pixeldata, sizeof(pixeldata), 1, fp) != 1) { fprintf(stderr, "writing output-file failed\n"); exit(1); } fclose(fp); } int main(int argc, char* argv[]) { if(argc != 2) { fprintf(stderr, "usage: %s <icon.bin>\n", argv[0]); exit(0); } FILE* fp = fopen(argv[1], "rb"); if(fp == NULL) { fprintf(stderr, "input file not found\n"); exit(1); } int f_len = flength(fp); char* f_buf = malloc(f_len); if(f_buf == NULL) { fprintf(stderr, "not enough memory\n"); exit(1); } if(fread(f_buf, f_len, 1, fp) != 1) { fprintf(stderr, "file read failure\n"); exit(1); } char dirname[256]; snprintf(dirname, sizeof(dirname), "%s.out", argv[1]); mkdir(dirname, 0777); chdir(dirname); bannerstruct* bnr = (bannerstruct*) f_buf; // check magic if(be16(&bnr->version) != BNR_VER) { fprintf(stderr, "invalid banner icon (magic mismatch)\n"); exit(1); } // extract default bitmap do_bitmap(bnr->bitmap, bnr->palette, "default.ppm"); // loop through all sequences u16* pseq = bnr->sequence; u16 seq, i; for(i=0; (seq = be16((u8*) pseq+i)) != 0; i++) { // masking out int bid = (seq&0x7); int pid = (seq&0x38)>>3; // write to logfile char fname[256]; snprintf(fname, sizeof(fname), "seq#%d.txt", i); FILE* flog = fopen(fname, "w+"); if(flog == NULL) { fprintf(stderr, "log-file couldn't be created\n"); exit(1); } fprintf(flog, "duration : %d frames\n", (seq&0xFF00)>>8); fprintf(flog, "bitmap : #%d\n", bid); fprintf(flog, "palette : #%d\n", pid); fclose(flog); // todo: flipz! if(seq & FLAG_FLIPV = FLAG_FLIPV) fprintf(stderr, "warning: vertical flip ignored on sequence #%d\n", i); if(seq & FLAG_FLIPH = FLAG_FLIPH) fprintf(stderr, "warning: horizontal flip ignored on sequence #%d\n", i); // change extension to .ppm char* dot_pos = strchr(fname, '.'); strcpy(dot_pos, ".ppm"); // extract bitmap to file do_bitmap(bnr->bitmaps[bid], bnr->palettes[pid], fname); } fclose(fp); free(f_buf); return 0; }