프로그래머포럼 C++Builder 작은모임 빌더라운지 담당 임펠리테리입니다.
윈도우즈엔 아이콘을 불러쓰기 위한 각종 API가 충분히 마련되어 있으니
아이콘 화일의 구조를 알 필요는 별로 없을 거 같은데요.. 그래도 기왕에
질문하셨으니 소스를 하나 보여드리지요. 아래는 제가 옛날에 도스용으로
아이콘 관련 프로그램을 만들기 위해 작성한 소스입니다. 옛날에 일반적으
로 알려진 아이콘 화일의 구조를 조금 더 분석하여 수정한 헤더입니다.
분석해 보시면 아이콘 파일의 구조는 알수 있으실겁니다. 참고로 출력에는
한라프로 함수를 사용하였습니다. 하지만 윈도우즈에서는 관련 api를 쓰시는
걸 권하고 싶군요.
#ifndef __ICOHDR_HPP
#define __ICOHDR_HPP
#include <fcntl.h>
#include <io.h>
#include <stdio.h>
#include <alloc.h>
#include <string.h>
#include <hanlib.h>
#include <hanout.h>
#include <hanmeq.h>
#include <hanmou.h>
#include <hancolor.h>
typedef struct {
unsigned int idReserved; // id byte (0)
unsigned int idType; // icon type (1)
unsigned int idCount; // # of images
} ICOHDR; // size : 6 byte
typedef struct {
unsigned char bWidth; // width of image (32)
unsigned char bHeight; // height of image (32)
unsigned int bColorCount; // # of color (16)
unsigned int wPlanes; // (0)
unsigned int wBitCount; // (0)
unsigned long dwBytesInRes; // image block size
unsigned long dwImageOffset; // adress of image block
} ICOENTRY; // size : 16 byte
#endif
#define MAXIMAGE 50
#define OPEN_ERROR -1
#define NOT_ICO 0
#define IS_ICO 1
typedef struct {
byte W; // width of image (32)
byte H; // height of image (32)
unsigned int C; // # of color (16)
byte *andmask; // AND mask image
byte *xormask; // XOR mask image
} IENTRY;
int hreadico(char *ifile, IENTRY *ientry[]);
int isico(char *ifile);
void hputico(int xp, int yp, IENTRY *item);
void freeico(IENTRY *item);
// ICOLIB.CPP : Lib for Windows ICO file accessing (all image in a file)
#include "icohdr.h"
int hreadico(char *ifile, IENTRY **ientry)
{
ICOHDR IcoHdr;
ICOENTRY *IcoEntry[MAXIMAGE];
unsigned long ioffset[MAXIMAGE];
byte **andlinebuf, **xorlinebuf;
unsigned int andisize, xorisize, andlbyte, xorlbyte, nImage;
register int i, l;
FILE *Istream;
if((Istream=fopen(ifile, "rb"))==NULL)
return OPEN_ERROR;
fread(&IcoHdr, sizeof(ICOHDR), 1, Istream);
if(IcoHdr.idReserved!=0 :: IcoHdr.idType!=1)
{
fclose(Istream);
return NOT_ICO;
}
nImage = (IcoHdr.idCount>MAXIMAGE ? MAXIMAGE : IcoHdr.idCount);
for(i=0; i<nImage; i++)
{
IcoEntry[i] = (ICOENTRY *)malloc(sizeof(ICOENTRY));
ientry[i] = (IENTRY *)malloc(sizeof(IENTRY));
fread(IcoEntry[i], sizeof(ICOENTRY), 1, Istream);
ientry[i]->W = IcoEntry[i]->bWidth;
ientry[i]->H = IcoEntry[i]->bHeight;
ientry[i]->C = IcoEntry[i]->bColorCount;
ioffset[i] = IcoEntry[i]->dwImageOffset+104;
free(IcoEntry[i]);
}
for(i=0; i<nImage; i++)
{
andlbyte = ientry[i]->W / (ientry[i]->C==16 ? 2 : 8);
xorlbyte = ientry[i]->W / 8;
andisize = ientry[i]->H * andlbyte;
xorisize = ientry[i]->H * xorlbyte;
ientry[i]->andmask = (byte *)malloc(andisize);
ientry[i]->xormask = (byte *)malloc(xorisize);
fseek(Istream, ioffset[i], SEEK_SET);
fread(ientry[i]->andmask, andisize, 1, Istream);
fread(ientry[i]->xormask, xorisize, 1, Istream);
// reverse XOR mask colors (WHITE <---> BLACK)
for(l=0; l<xorisize; l++)
(ientry[i]->xormask)[l] = 0xff-(ientry[i]->xormask)[l];
// reverse lines (UP <---> DOWN)
andlinebuf = (byte **)calloc(ientry[i]->W, sizeof(byte *));
xorlinebuf = (byte **)calloc(ientry[i]->W, sizeof(byte *));
for(l = 0; l < ientry[i]->H; l++)
{
andlinebuf[l] = (byte *)malloc(andlbyte);
memcpy(andlinebuf[l], ientry[i]->andmask+andlbyte*(ientry[i]->H-l-1), andlbyte);
xorlinebuf[l] = (byte *)malloc(xorlbyte);
memcpy(xorlinebuf[l], ientry[i]->xormask+xorlbyte*(ientry[i]->H-l-1), xorlbyte);
}
for(l = 0; l < ientry[i]->H; l++)
{
memcpy(ientry[i]->andmask+andlbyte*l, andlinebuf[l], andlbyte);
free(andlinebuf[l]);
memcpy(ientry[i]->xormask+xorlbyte*l, xorlinebuf[l], xorlbyte);
free(xorlinebuf[l]);
}
free(andlinebuf);
free(xorlinebuf);
}
fclose(Istream);
return nImage;
}
int isico(char *ifile)
{
FILE *Istream;
ICOHDR IcoHdr;
if((Istream=fopen(ifile, "rb"))==NULL)
return OPEN_ERROR;
fread(&IcoHdr, sizeof(ICOHDR), 1, Istream);
fclose(Istream);
return IcoHdr.idReserved==0&&IcoHdr.idType==1 ? IS_ICO : NOT_ICO;
}
void hputico(int xp, int yp, IENTRY *item)
{
hputsprite(xp, yp, xp+item->W-1, yp+item->H-1, item->andmask, item->xormask);
}
void freeico(IENTRY *item)
{
free(item);
}
|