Difference between revisions of "User:Remark/Icon2ppm.c"

From DSiBrew
Jump to navigation Jump to search
m (Added Syntax-coloring.)
Line 1: Line 1:
  // DSi icon2ppm - #dsidev
+
<source lang="c">
  // written by remark
+
// DSi icon2ppm - #dsidev
  // thanks to loopy_, bLASTY
+
// 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];
 +
}
 
    
 
    
   // Copyright 2007,2008  Segher Boessenkool  <segher@kernel.crashing.org>
+
#define BNR_VER 0x0301
   // Licensed under the terms of the GNU GPL, version 2
+
#define FLAG_FLIPV 0x80
   // http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
+
#define FLAG_FLIPH 0x40
 +
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);
 
    
 
    
   #include <stdio.h>
+
   // fix 8x8 tiling
   #include <unistd.h>
+
   u8 tilebuf[0x204];
   typedef unsigned long u32;
+
   int x,y,z;
   typedef unsigned short u16;
+
   for(x=0; x<4; x++)
   typedef unsigned char u8;
+
   {
 +
    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);
 +
      }
 +
    }
 +
  }
 
    
 
    
   u16 be16(const u8 *p)
+
   // convert to rgb888
 +
  int i,j;
 +
  u8 pixeldata[32*32][3];
 +
  for(i=0; i<0x200; i++)
 
   {
 
   {
     return (p[0] << 8) | p[1];
+
     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);
 +
    }
 
   }
 
   }
   u32 be32(const u8 *p)
+
    
 +
  if(fwrite(pixeldata, sizeof(pixeldata), 1, fp) != 1)
 
   {
 
   {
     return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
+
     fprintf(stderr, "writing output-file failed\n");
 +
    exit(1);
 
   }
 
   }
 +
 +
  fclose(fp);
 +
}
 
    
 
    
  #define BNR_VER 0x0301
+
int main(int argc, char* argv[])
  #define FLAG_FLIPV 0x80
+
{
   #define FLAG_FLIPH 0x40
+
   if(argc != 2)
   typedef struct {
+
   {
     u16 version;
+
     fprintf(stderr, "usage: %s <icon.bin>\n", argv[0]);
    u16 crcs[4];
+
     exit(0);
    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)
+
   FILE* fp = fopen(argv[1], "rb");
 +
  if(fp == NULL)
 
   {
 
   {
     int pos,end;
+
     fprintf(stderr, "input file not found\n");
    pos = ftell (f);
+
     exit(1);
    fseek (f, 0, SEEK_END);
 
    end = ftell (f);
 
     fseek (f, pos, SEEK_SET);
 
    return end;
 
 
   }
 
   }
 
    
 
    
   void do_bitmap(u8* bitmap, u16* palette, char* fname)
+
   int f_len = flength(fp);
 +
  char* f_buf = malloc(f_len);
 +
  if(f_buf == NULL)
 
   {
 
   {
     FILE *fp = fopen(fname, "wb");
+
     fprintf(stderr, "not enough memory\n");
    if (fp == NULL)
+
    exit(1);
    {
+
  }
      fprintf(stderr, "file cannot be opened: %s\n", fname);
+
  if(fread(f_buf, f_len, 1, fp) != 1)
      exit(1);
+
  {
    }
+
    fprintf(stderr, "file read failure\n");
    fprintf(fp, "P6 %d %d 255\n", 32, 32);
+
     exit(1);
   
+
  }
    // fix 8x8 tiling
+
 
    u8 tilebuf[0x204];
+
  char dirname[256];
    int x,y,z;
+
  snprintf(dirname, sizeof(dirname), "%s.out", argv[1]);
    for(x=0; x<4; x++)
+
  mkdir(dirname, 0777);
    {
+
  chdir(dirname);
      for(y=0; y<8; y++)
+
 
      {
+
  bannerstruct* bnr = (bannerstruct*) f_buf;
        for(z=0; z<8; z++)
+
  // check magic
        {
+
  if(be16((u8*)&bnr->version) != BNR_VER)
          memcpy(tilebuf+(x*128)+(16*y)+(4*z),
+
  {
            bitmap+(x*128)+(32*z)+(4*y), 4);
+
    fprintf(stderr, "invalid banner icon (magic mismatch)\n");
        }
+
    exit(1);
      }
 
     }
 
   
 
    // 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[])
+
   // 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++)
 
   {
 
   {
     if(argc != 2)
+
     // masking out
     {
+
     int bid = (seq&0x7);
      fprintf(stderr, "usage: %s <icon.bin>\n", argv[0]);
+
     int pid = (seq&0x38)>>3;
      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];
+
    // write to logfile
     snprintf(dirname, sizeof(dirname), "%s.out", argv[1]);
+
     char fname[256];
    mkdir(dirname, 0777);
+
     snprintf(fname, sizeof(fname), "seq#%d.txt", i);
    chdir(dirname);
 
 
      
 
      
     bannerstruct* bnr = (bannerstruct*) f_buf;
+
     FILE* flog = fopen(fname, "w+");
    // check magic
+
     if(flog == NULL)
     if(be16((u8*)&bnr->version) != BNR_VER)
 
 
     {
 
     {
       fprintf(stderr, "invalid banner icon (magic mismatch)\n");
+
       fprintf(stderr, "log-file couldn't be created\n");
 
       exit(1);
 
       exit(1);
 
     }
 
     }
 
      
 
      
     // extract default bitmap
+
     fprintf(flog, "duration : %d frames\n", (seq&0xFF00)>>8);
     do_bitmap(bnr->bitmap, bnr->palette, "default.ppm");
+
     fprintf(flog, "bitmap   : #%d\n", bid);
 +
    fprintf(flog, "palette  : #%d\n", pid);
 +
    fclose(flog);
 
      
 
      
     // loop through all sequences
+
     // todo: flipz!
    u16* pseq = bnr->sequence;
+
    if((seq & FLAG_FLIPV) == FLAG_FLIPV)
    u16 seq, i;
+
      fprintf(stderr, "warning: vertical flip ignored on sequence #%d\n", i);
    for(i=0; (seq = be16((u8*) pseq+i)) != 0; i++)
+
    if((seq & FLAG_FLIPH) == FLAG_FLIPH)
    {
+
      fprintf(stderr, "warning: horizontal flip ignored on sequence #%d\n", 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);
+
     // change extension to .ppm
     free(f_buf);
+
    char* dot_pos = strchr(fname, '.');
 +
     strcpy(dot_pos, ".ppm");
 
      
 
      
     return 0;
+
     // extract bitmap to file
 +
    do_bitmap(bnr->bitmaps[bid], bnr->palettes[pid], fname);
 
   }
 
   }
 +
 +
  fclose(fp);
 +
  free(f_buf);
 +
 
 +
  return 0;
 +
}
 +
</source>

Revision as of 10:26, 22 May 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 0x80
#define FLAG_FLIPH 0x40
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((u8*)&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;
}