cielavenir

BMP <-> initlogo.rle converter

Dec 19th, 2012
216
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.45 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <stdlib.h>
  4. #include <sys/stat.h>
  5. #include <libnsbmp.h>
  6.  
  7. typedef unsigned char u8;
  8. typedef unsigned int u32;
  9. u8 buf[256];
  10.  
  11. #if defined(WIN32) || (!defined(__GNUC__) && !defined(__clang__))
  12.     #include <fcntl.h>
  13.     #define initstdio() setmode(fileno(stdin),O_BINARY),setmode(fileno(stdout),O_BINARY),setmode(fileno(stderr),O_BINARY);
  14. #else
  15.     #include <unistd.h>
  16.     #define initstdio()
  17. #endif
  18.  
  19. static unsigned int read32(const void *p){
  20.     const unsigned char *x=(const unsigned char*)p;
  21.     return x[0]|(x[1]<<8)|(x[2]<<16)|(x[3]<<24);
  22. }
  23.  
  24. static void write32(void *p, const unsigned int n){
  25.         unsigned char *x=(unsigned char*)p;
  26.         x[0]=n&0xff,x[1]=(n>>8)&0xff,x[2]=(n>>16)&0xff,x[3]=(n>>24)&0xff;
  27. }
  28.  
  29. static unsigned short read16(const void *p){
  30.     const unsigned char *x=(const unsigned char*)p;
  31.     return x[0]|(x[1]<<8);
  32. }
  33.  
  34. static void write16(void *p, const unsigned short n){
  35.         unsigned char *x=(unsigned char*)p;
  36.         x[0]=n&0xff,x[1]=(n>>8)&0xff;
  37. }
  38.  
  39. static void *bitmap_create(int width, int height, unsigned int state){return malloc(width*height*4);}
  40.  
  41. static void bitmap_set_suspendable(void *bitmap, void *private_word,
  42.                  void (*invalidate)(void *bitmap, void *private_word)){}
  43.  
  44. //static void invalidate(void *bitmap, void *private_word){}
  45.  
  46. static unsigned char *bitmap_get_buffer(void *bitmap){return bitmap;}
  47.  
  48. static size_t bitmap_get_bpp(void *bitmap){return 4;}
  49.  
  50. static void bitmap_destroy(void *bitmap){free(bitmap);}
  51.  
  52. int main(const int argc, const char **argv){
  53.     initstdio();
  54.     if(argc<3){
  55.         fprintf(stderr,
  56.             "androidlogo rle/raw in.bmp >out.rle\n"
  57.             "androidlogo width rle/raw out.bmp [16] <in.rle\n"
  58.         );
  59.         return -1;
  60.     }
  61.  
  62.     int pixels=0,count=0,color,last;
  63.     if(argc==3){ //encode
  64.         struct stat st;
  65.         int x,y;
  66.         FILE *in=fopen(argv[2],"rb");
  67.         if(!in){
  68.             fprintf(stderr,"cannot open %s\n",argv[2]);
  69.             return 1;
  70.         }
  71.         fstat(fileno(in),&st);
  72.         void *imgbuf=malloc(st.st_size);
  73.         fread(imgbuf,1,st.st_size,in);
  74.         fclose(in);
  75.  
  76.         bmp_image gif;
  77.         bmp_bitmap_callback_vt vt={
  78.             bitmap_create,
  79.             bitmap_destroy,
  80.             bitmap_set_suspendable,
  81.             bitmap_get_buffer,
  82.             bitmap_get_bpp
  83.         };
  84.  
  85.         bmp_create(&gif,&vt);
  86.         if(bmp_analyse(&gif, st.st_size, imgbuf)||bmp_decode(&gif)){bmp_finalise(&gif);free(imgbuf);return 1;}
  87.         free(imgbuf);
  88.  
  89.         for(y=0;y<gif.height;y++){
  90.             for(x=0;x<gif.width;x++){
  91.                 u32 coor=y*gif.width+x;
  92.                 u8 b=((((u32*)gif.bitmap)[coor]&0xff0000)>>16)&0xff;
  93.                 u8 g=((((u32*)gif.bitmap)[coor]&0x00ff00)>>8)&0xff;
  94.                 u8 r=((((u32*)gif.bitmap)[coor]&0x0000ff)>>0)&0xff;
  95.                 color=((r>>3)<<11)|((g>>2)<<5)|((b>>3)<<0);
  96.                 if(!strcasecmp(argv[1],"raw")){
  97.                     write16(buf,color);
  98.                     fwrite(buf,1,2,stdout);
  99.                 }else{
  100.                     if(count){
  101.                         if(color==last&&count<65535){
  102.                             count++;continue;
  103.                         }else{
  104.                             write16(buf,count);
  105.                             write16(buf+2,last);
  106.                             fwrite(buf,1,4,stdout);
  107.                         }
  108.                     }
  109.                     last=color;
  110.                     count=1;
  111.                 }
  112.             }
  113.         }
  114.         if(count){
  115.             write16(buf,count);
  116.             write16(buf+2,color);
  117.             fwrite(buf,1,4,stdout);
  118.         }
  119.         bmp_finalise(&gif);
  120.     }else{ //decode
  121.         int width=strtol(argv[1],NULL,0),height;
  122.         if(!width||(width&3)){
  123.             fprintf(stderr,"width must be 4x...\n");
  124.             return 1;
  125.         }
  126.         FILE *out=fopen(argv[3],"wb");
  127.         if(!out){
  128.             fprintf(stderr,"cannot open %s\n",argv[3]);
  129.             return 1;
  130.         }
  131.         int bytesPerPixel=3;
  132.         if(argc>4)bytesPerPixel=2;
  133.         memset(buf,0,54);
  134.         fwrite(buf,1,54,out);
  135.         for(;fread(buf,1,2,stdin)>1;){
  136.             if(!strcasecmp(argv[2],"raw")){
  137.                 count=1;
  138.                 color=read16(buf);
  139.             }else{
  140.                 count=read16(buf);
  141.                 fread(buf,1,2,stdin);
  142.                 color=read16(buf);
  143.             }
  144.             pixels+=count;
  145.             for(;count;count--){
  146.                 if(bytesPerPixel==3){
  147.                     //transform RGB565 to BGR888
  148.                     fputc(((color>>0)&0x1f)<<3,out);
  149.                     fputc(((color>>5)&0x3f)<<2,out);
  150.                     fputc(((color>>11)&0x1f)<<3,out);
  151.                 }else{
  152.                     int col16=(((color>>11)&0x1f)<<10) | (((color>>6)&0x1f)<<5) | (((color>>0)&0x1f)<<0);
  153.                     write16(buf,col16);
  154.                     fwrite(buf,1,2,out);
  155.                 }
  156.             }
  157.         }
  158.         height=pixels/width;
  159.         fseek(out,0,SEEK_SET);
  160.         buf[0]='B',buf[1]='M';
  161.         write32(buf+2,54+width*height*bytesPerPixel);
  162.         write32(buf+10,54);
  163.         write32(buf+14,40);
  164.         write32(buf+18,width);
  165.         write32(buf+22,-height); //argh...
  166.         write16(buf+26,1);
  167.         write16(buf+28,bytesPerPixel*8);
  168.         write32(buf+34,width*height*bytesPerPixel);
  169.         fwrite(buf,1,54,out);
  170.         fclose(out);
  171.     }
  172.     return 0;
  173. }
Advertisement
Add Comment
Please, Sign In to add comment