/*--------------------------------------------------------------------------*/ /* */ /* Ico2bmp - Small utility program, which reads a icon file (.ico), extracts*/ /* the color part of the icon, and generates a bitmap file (.bmp). */ /* */ /* Author: Niels Erik Holm, ICL DATA A/S, Copenhagen Denmark, neh@rci.dk */ /* No copyrights apply, no Warranty */ /* */ /*--------------------------------------------------------------------------*/ #include #include #include #include #include char * Version = "Ico2bmp v1.0 - Extracts color bitmap from icon file - Author: neh@rci.dk"; typedef struct { WORD icoReserved; /* Reserved, must be set to 0 */ WORD icoResourceType; /* Resource type, 1 for icon resources */ WORD icoResourceCount; /* Number of images in the file */ } IconFileHeader; typedef struct { BYTE Width; /* Width in pixels */ BYTE Height; /* Height in pixels */ BYTE ColorCount; /* Number of colors */ BYTE Reserved1; WORD Reserved2; WORD Reserved3; DWORD icoDIBSize; /* Size in bytes of the pixel array */ DWORD icoDIBOffset; /* Offset in bytes from beginning of file */ /* to pixel array. */ } IconRscDir; typedef struct { IconFileHeader IHead; /* Icon file header */ IconRscDir IDir; /* Icon resource directory */ BYTE IBits[1000]; } IconFile; BITMAPFILEHEADER bmFH; BITMAPINFOHEADER bmIH; RGBQUAD bmCol[16]; unsigned char Idata[1000]; unsigned char Odata[1000]; int opterr = 1; int optind = 1; int optopt; char * optarg; struct find_t fb; int MoreFiles; static int getopt(int,char **,char *); static int ProcessFile(char *,char *); static void ManipulateBits(BYTE *,BYTE *,int); static void usage(void); main(argc,argv) int argc; char *argv[]; { int opt,attr; char * Fptr; char InFileSpec[64]; char FirstName[64]; char InName[64]; char OutName[64]; InFileSpec[0] = 0; attr = 0; while ((opt = getopt(argc,argv,"hi:")) != -1) switch (opt) { case 'h': usage(); exit(1); break; case 'i': strcpy(InFileSpec,optarg); break; } if (InFileSpec[0] == 0) { usage(); exit(1); } if ((Fptr = strchr(InFileSpec,'.')) == NULL) strcat(InFileSpec,".ico"); MoreFiles = (_dos_findfirst(InFileSpec,attr,&fb) == 0); if (!MoreFiles) { fprintf (stderr,"No files matching %s\n",InFileSpec); exit(1); } strcpy(FirstName,fb.name); while (MoreFiles) { strcpy(InName,fb.name); strcpy(OutName,InName); Fptr = strchr(OutName,'.'); strcpy(Fptr,".bmp"); (void) ProcessFile(InName,OutName); MoreFiles = ((_dos_findnext(&fb)==0) && (strcmp(FirstName,fb.name)!=0)); } } static int ProcessFile(char * InFileName,char * OutFileName) { FILE * Ifile; FILE * Ofile; IconRscDir* pIRD; BITMAPINFOHEADER * pBMIH; RGBQUAD * pRGB; BYTE * pColorData; BYTE * pMonoData; int i,j,Ino,Cno,DataNo,ColorTabSize,BitMapSize,Pixels,BitsPerPixel; char * Iptr; unsigned char * Bptr; if ((Ifile = fopen(InFileName,"rb")) == NULL) { fprintf (stderr,"Error opening input file %s\n",InFileName); return(0); } fread (Idata,1,sizeof(Idata),Ifile); fclose(Ifile); if ((Ofile = fopen(OutFileName,"wb")) == NULL) { fprintf (stderr,"Error opening output file %s\n",OutFileName); return(0); } fprintf (stdout,"Processing %s -> %s",InFileName,OutFileName); Iptr = Idata; if (((IconFileHeader *)Iptr)->icoReserved != 0) { fprintf (stderr,"\nSorry! Invalid icon file.\n"); return(0); } Ino = ((IconFileHeader *)Iptr)->icoResourceCount; if (Ino != 1) { fprintf (stderr,"\nSorry! Ico2bmp can only handle icon file with one icons.\n"); return(0); } Iptr += sizeof(IconFileHeader); pIRD = (IconRscDir *)Iptr; pBMIH= (BITMAPINFOHEADER *)(Idata + pIRD->icoDIBOffset); pRGB = (RGBQUAD *)((BYTE *)pBMIH+sizeof(BITMAPINFOHEADER)); ColorTabSize = pIRD->ColorCount*sizeof(RGBQUAD); pColorData = (BYTE *)((BYTE *)pRGB+ColorTabSize); BitsPerPixel = pBMIH->biBitCount; Pixels = pIRD->Width*pIRD->Height*BitsPerPixel; BitMapSize = Pixels/8; pMonoData = (BYTE *)(pColorData + BitMapSize); Cno=pBMIH->biBitCount; if (Cno==1) Cno=2; else if (Cno==4) Cno=16; else if (Cno==8) Cno=256; else if (Cno==24) Cno=0; if (Cno != 16) { fprintf (stderr,"\nSorry! Ico2bmp can only handle 16 color icons\n"); return(0); } bmFH.bfType = 'B' | 'M'<<8; bmFH.bfSize = sizeof(bmFH)+sizeof(bmIH)+ColorTabSize+BitMapSize; bmFH.bfOffBits = sizeof(bmFH)+sizeof(bmIH)+ColorTabSize; bmIH.biSize = pBMIH->biSize; bmIH.biWidth = pBMIH->biWidth; bmIH.biHeight = pBMIH->biHeight/2; bmIH.biPlanes = pBMIH->biPlanes; bmIH.biBitCount = pBMIH->biBitCount; bmIH.biCompression = pBMIH->biCompression; bmIH.biSizeImage = BitMapSize; bmIH.biXPelsPerMeter = pBMIH->biXPelsPerMeter; bmIH.biYPelsPerMeter = pBMIH->biYPelsPerMeter; bmIH.biClrUsed = pBMIH->biClrUsed; bmIH.biClrImportant = Cno; for (i=0;i [-h]\n"); fprintf (stdout,"\n"); fprintf (stdout," -h: Display this help\n"); fprintf (stdout," -i: Name of input file. If no extension is specified .ico is used.\n"); fprintf (stdout," Wildcards are allowed. Ex. -i *.ico\n"); } #define index strchr #define ERR(s, c) if(opterr){\ extern int write();\ char errbuf[2];\ errbuf[0] = c; errbuf[1] = '\n';\ (void) fprintf(stderr, argv[0], (unsigned)strlen(argv[0]));\ (void) fprintf(stderr, s, (unsigned)strlen(s));\ (void) fprintf(stderr, errbuf, 2);} static int getopt(int argc, char ** argv, char * opts) { static int sp = 1; register int c; register char *cp; if(sp == 1) if(optind >= argc || argv[optind][0] != '-' || argv[optind][1] == '\0') return(-1); else if(strcmp(argv[optind], "--") == 0) { optind++; return(-1); } optopt = c = argv[optind][sp]; if(c == ':' || (cp=index(opts, c)) == 0) { ERR(": illegal option -- ", c); if(argv[optind][++sp] == '\0') { optind++; sp = 1; } return('?'); } if(*++cp == ':') { if(argv[optind][sp+1] != '\0') optarg = &argv[optind++][sp+1]; else if(++optind >= argc) { ERR(": option requires an argument -- ", c); sp = 1; return('?'); } else optarg = argv[optind++]; sp = 1; } else { if(argv[optind][++sp] == '\0') { sp = 1; optind++; } optarg = 0; } return(c); }