home *** CD-ROM | disk | FTP | other *** search
/ Chip 2001 Mobile / Chip_Mobile_2001.iso / palm / spiele / argon / argon.exe / src / graphics / bmp2bin.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-01-21  |  4.1 KB  |  187 lines

  1. /*
  2.   bmp2bin.c  image converter tool for 'Argon V'
  3.  
  4.   T.Harbaum@tu-bs.de - http://www.ibr.cs.tu-bs.de/~harbaum/pilot
  5.  
  6.   This program is distributed in the hope that it will be useful,
  7.   but WITHOUT ANY WARRANTY; without even the implied warranty of
  8.   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  9.   GNU General Public License for more details.
  10.  
  11. */
  12.  
  13. #include <stdio.h>
  14.  
  15. #define MAGIC 0x4d42
  16.  
  17. #pragma pack(1)
  18.  
  19. struct bmp16_hdr {
  20.   unsigned short magic;
  21.   unsigned short dummy0[8];
  22.   unsigned long  width, height;
  23.   unsigned short dummy1;
  24.   unsigned short bpp;
  25.   unsigned long  dummy2;
  26.   unsigned long  length;
  27.   unsigned long  dummy3[2];
  28.   unsigned long  colors;
  29.   unsigned long  colors2;
  30. };
  31.  
  32. struct color {
  33.   unsigned char r,g,b,x;
  34. };
  35.  
  36. #pragma pack(4)
  37.  
  38. int
  39. main(int argc, char *argv[]) {
  40.   FILE   *in, *out;
  41.   struct bmp16_hdr bmphdr;
  42.   struct color colors[256];
  43.   int i, j, colass[256], used[256], x, y, mask, colcnt, pwid, white, n;
  44.   unsigned char *imgsrc, p;
  45.  
  46.   if(argc!=3) {
  47.     puts("usage: bmp2bin infile outfile");
  48.     exit(1);
  49.   }
  50.  
  51.   if((in = fopen(argv[1], "rb"))==0) {
  52.     puts("unable to open input file");
  53.     exit(1);
  54.   }
  55.  
  56.   if((out = fopen(argv[2], "wb"))==0) {
  57.     puts("unable to open output file");
  58.     exit(1);
  59.   }
  60.  
  61.   fread(&bmphdr, sizeof(struct bmp16_hdr), 1l, in);
  62.  
  63.   /* this doesn't work on big endian, but the rest doesn't either */
  64.   if(bmphdr.magic != MAGIC) {
  65.     puts("illegal bitmap header magic");
  66.     exit(1);
  67.   }
  68.  
  69.   /* verify picture height */  
  70.   if((bmphdr.width != bmphdr.height+2)&&
  71.      ((bmphdr.width!=194)||(bmphdr.height!=160))) {
  72.     if(bmphdr.width != 2*(bmphdr.height+2)) {
  73.       printf("illegal bitmap size (%dx%d)\n", bmphdr.width, bmphdr.height);
  74.       exit(1);
  75.     } else {
  76.       printf("converting with mask %dx%d\n", (bmphdr.width/2)-2, bmphdr.height);
  77.       mask = 1;
  78.     }
  79.   } else
  80.     mask = 0;
  81.   
  82.   /* pixel depth */
  83.   if(bmphdr.bpp!=8) {
  84.     printf("illegal picture depth %d\n", bmphdr.bpp);
  85.     exit(1);
  86.   }
  87.  
  88.   /* read colors */
  89.   fread(colors, bmphdr.colors, sizeof(struct color), in);
  90.  
  91.   for(i=0;i<bmphdr.colors;i++) used[i]=0;
  92.  
  93.   for(colcnt=0,i=0;i<bmphdr.colors;i++) {
  94.  
  95.     /* calculate color assignment */
  96.     j = ((colors[i].r + colors[i].g + colors[i].b)*15)/(3*0xf0);
  97.     if(j>15) { puts("alarm"); exit(1); }
  98.     
  99.     if(!used[j]) colcnt++;
  100.  
  101.     colass[i] = j;
  102.     used[j] = 1;
  103.  
  104.     if(j==15) white=i;
  105.   }
  106.  
  107.   if(colcnt>16) {
  108.     printf("too many colors in use (%d)\n", colcnt);
  109.     exit(1);
  110.   }
  111.  
  112.   pwid = (bmphdr.width+3)&~3;
  113.  
  114.   imgsrc = (unsigned char*)malloc(pwid*bmphdr.height);
  115.   fread(imgsrc, pwid*bmphdr.height, 1l, in);
  116.  
  117.   if(!mask) {
  118.     /* scan plain picture */
  119.     for(y=0;y<bmphdr.height;y++) {
  120.       for(x=0;x<(bmphdr.width-2)/2;x++) {
  121.     
  122.     /* get two pixels */
  123.     i = imgsrc[((bmphdr.length/bmphdr.height)* (bmphdr.height-1-y)) + 2*x];
  124.     j = imgsrc[((bmphdr.length/bmphdr.height)* (bmphdr.height-1-y)) + 2*x+1];
  125.     
  126.     /* write them into one byte */
  127.     fputc(~((colass[i]<<4)|(colass[j])), out);
  128.       }
  129.     }
  130.   } else {
  131.     /* scan picture with mask */
  132.     for(y=0;y<bmphdr.height;y++) {
  133.  
  134.       /* scan mask */
  135.       for(p=0,x=0;x<(bmphdr.width-4)/4;x++) {
  136.  
  137.     /* get two pixels */
  138.     i = imgsrc[(pwid * (bmphdr.height-1-y)) + 
  139.           2*x   + bmphdr.width/2];
  140.     j = imgsrc[(pwid * (bmphdr.height-1-y)) + 
  141.           2*x+1 + bmphdr.width/2];
  142.  
  143.     if(((colass[i]!=0)&&(colass[i]!=15)) ||
  144.        ((colass[j]!=0)&&(colass[j]!=15))) {
  145.       printf("illegal color in mask\n");
  146.       exit(1);
  147.     }
  148.  
  149.     /* write them into one byte */
  150.     p <<= 2;
  151.     if(!colass[i]) p |= 2;
  152.     if(!colass[j]) p |= 1;
  153.  
  154.     if((x&3) == 3) {
  155.       /* write mask byte */
  156.       fputc(p, out);
  157.       p=0;
  158.     }
  159.       }
  160.  
  161.       /* scan image */
  162.       for(x=0;x<(bmphdr.width-4)/4;x++) {
  163.  
  164.     /* get two pixels */
  165.     i = imgsrc[(pwid * (bmphdr.height-1-y)) + 8*n + 2*x];
  166.     j = imgsrc[(pwid * (bmphdr.height-1-y)) + 8*n + 2*x+1];
  167.     
  168.     /* verify mask */
  169.     if(colass[imgsrc[(pwid * (bmphdr.height-1-y)) + 
  170.             2*x   + bmphdr.width/2]] == 15) i = white;
  171.       
  172.     if(colass[imgsrc[(pwid * (bmphdr.height-1-y)) + 
  173.             2*x+1 + bmphdr.width/2]] == 15) j = white;
  174.       
  175.     /* write them into one byte */
  176.     fputc(~((colass[i]<<4)|(colass[j])), out);
  177.       }
  178.     }
  179.   }
  180.  
  181.   free(imgsrc);
  182.   
  183.   fclose(in);
  184.   fclose(out);
  185.   exit(0);
  186. }
  187.