#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <io.h>
typedef unsigned char BYTE;
typedef unsigned short WORD;
typedef unsigned long DWORD;
#pragma pack (1)
typedef struct {
WORD bfType;
DWORD bfSize;
WORD bfReserved1;
WORD bfReserved2;
DWORD bfOffBits;
} BMFH;
#pragma pack (1)
typedef struct {
DWORD biSize;
long biWidth;
long biHeight;
WORD biPlanes;
WORD biBitCount;
DWORD biCompression;
DWORD biSizeImage;
long biXPelsPerMeter;
long biYPelsPerMeter;
DWORD biClrUsed;
DWORD biClrImportant;
} BMIH;
typedef struct {
BYTE rgbBlue;
BYTE rebRed;
DWORD temp1;
BYTE rgbRed;
BYTE rgbReserved;
} RGBQUAD;
typedef struct {
BYTE rgbBlue;
BYTE rgbGreen;
BYTE rgbRed;
} RGB;
typedef struct {
BMFH Bmfh;
BMIH bmih;
RGBQUAD *pRgbQuad; //for 1,4, 8-bit bitmap
BYTE *plndex;
RGBQUAD *pRgb; //for 24-bit bitmap
} BMP;
DWORD Mtel_BMP_Fileheader(BYTE *buff, BMFH *pbmfh);
DWORD Mtel_BMP_Infoheder(BYTE *buff, DWORD INDEX, BMIH *pbmih);
DWORD Mtel_BMP_Palette(BYTE * buff, DWORD INDEX, RGB *ppalette, DWORD color );
DWORD Mtel_BMP_Rowdata(BYTE *buff, DWORD INDEX, BYTE *pRowData, BMIH *pbmih, DWORD rowdata_size);
DWORD Mtel_BMP_TxtOut(BYTE *newname, BMFH *pbmfh, BMIH *pbmih, RGB *ppalette, BYTE *pRowData, DWORD color, DWORD rowdata_size);
main()
{
FILE * fp;
BYTE * buff;
BYTE source[80] = "temp.bmp";
BYTE destination[80] = "out.txt";
BMFH bmfh;
BMFH *pbmfh;
BMIH bmih;
BMIH *pbmih;
RGB *ppalette;
BYTE *pRowData;
WORD color;
DWORD buff_size;
DWORD INDEX=0;
DWORD rowdata_size;
RGBQUAD test;
int temp;
temp = sizeof(test);
temp = sizeof(BMFH);
temp = sizeof(BMIH);
/*
printf("\nEnter source filename: "); // 파일 이름 입력
gets(source);
printf("\nEnter destination filename: "); // 변환할 파일 이름 입력
gets(destination);
*/
if((fp = fopen(source, "rb")) != NULL)
{
buff_size = filelength(fileno(fp));
buff = (BYTE*)malloc(buff_size);
fread(buff, 1, buff_size, fp);
pbmfh = &bmfh;
INDEX = Mtel_BMP_Fileheader(buff, pbmfh);
pbmih = &bmih;
INDEX += Mtel_BMP_Infoheder(buff, INDEX, pbmih);
/* bits per pixels에 따른 palette 처리 */
switch(bmih.biBitCount)
{
case 1:
color = 2;
ppalette = (RGB*)malloc(color*sizeof(RGB));
INDEX += Mtel_BMP_Palette(buff, INDEX, ppalette, color);
break;
case 4:
color = 16;
ppalette = (RGB*)malloc(color*sizeof(RGB));
INDEX += Mtel_BMP_Palette(buff, INDEX, ppalette, color);
break;
case 8:
color = 256;
ppalette = (RGB*)malloc(color*sizeof(RGB));
INDEX += Mtel_BMP_Palette(buff, INDEX, ppalette, color);
break;
case 24:
break;
}
rowdata_size = (bmih.biWidth*bmih.biBitCount/8)*bmih.biHeight;
pRowData = (BYTE *)malloc(rowdata_size);
INDEX += Mtel_BMP_Rowdata(buff, INDEX, pRowData, pbmih, rowdata_size);
if (Mtel_BMP_TxtOut(destination, pbmfh, pbmih, ppalette, pRowData, color, rowdata_size ) == 0)
puts("\nConvert operation sucessful\n");
else
fprintf(stderr, "Error during convert operation");
}
else
fprintf(stderr, "\nError opening file %s.\n", source);
return 0;
}
DWORD Mtel_BMP_Fileheader(BYTE *buff, BMFH *pbmfh)
{
memcpy(pbmfh, buff, sizeof(BMFH));
return (sizeof(BMFH));
}
DWORD Mtel_BMP_Infoheder( BYTE *buff, DWORD INDEX, BMIH *pbmih)
{
memcpy(pbmih,buff+INDEX,sizeof(BMIH));
return (sizeof(BMIH));
}
DWORD Mtel_BMP_Palette(BYTE * buff, DWORD INDEX, RGB *ppalette, DWORD color )
{
WORD i = 0;
DWORD buff_pal_size ;
buff_pal_size = color*4;
for(i = 0; i< color; i++)
{
(ppalette+i)->rgbBlue = buff[INDEX];
(ppalette+i)->rgbGreen = buff[INDEX+1];
(ppalette+i)->rgbRed = buff[INDEX+2];
INDEX = INDEX+4;
}
//memcpy( ppalette, buff+INDEX, palette_size);
return (buff_pal_size);
}
DWORD Mtel_BMP_Rowdata(BYTE *buff, DWORD INDEX, BYTE *pRowData, BMIH *pbmih, DWORD rowdata_size)
{
DWORD bpw; // Byte Per Width 변수.
BYTE dummy_byte; // 4 byte 정렬을 위해 사용된 단위 width 당 dummy byte 수.
BYTE rest; // byte per width를 4로 나눈 나머지 이값에 따라 dummy byte의 수가 결정됨.
long i=0;
DWORD j=0,k=0;
DWORD temp_index = 0;
DWORD buff_rowdata_size; //buffer에 읽어온 실제 파일의 rowdata size(dummy byte포함)
bpw = (pbmih->biBitCount*pbmih->biWidth)/8; // Byte Per Width 계산.
rest = bpw%4;
/* dummy byte수 결정.*/
if(rest != 0)
dummy_byte = 4-rest;
else
dummy_byte = 0;
buff_rowdata_size = (bpw+dummy_byte)*pbmih->biHeight; //dummy byte를 포함한 전체 rowdata size를 구함.
temp_index = INDEX + buff_rowdata_size-1; //buffer 에서 가장 마지막 data를 가리키도록 tmep_index를 설정.
for(i=0 ; i<pbmih->biHeight ; i++) // RowData를 buff에서 아래쪽 부터 읽음.
{
temp_index = temp_index-dummy_byte;
for(j=bpw; j >=1 ; j--)
{
pRowData[bpw*i+j-1] = buff[temp_index--];
}
}
/* {
FILE* fp;
fp=fopen("reverse.bmp","wb");
memcpy(buff+54, pRowData,buff_rowdata_size);
fwrite(buff,1,54+ buff_rowdata_size,fp);
fclose(fp);
}*/
/* for(i=0; i<pbmih->biHeight; i++) // RowData를 buff에서 순서대로 읽음
{
for(j=0 ; j < bpw; j++)
{
pRowData[bpw*i+j] = buff[INDEX];
INDEX++;
}
INDEX = INDEX + dummy_byte;
}
{
FILE* fp;
fp=fopen("reverse.bmp","wb");
memcpy(buff+54, pRowData,buff_rowdata_size);
fwrite(buff,1,54+ buff_rowdata_size,fp);
fclose(fp);
}*/
for(k=0;k<50;k++)
{
INDEX=54;
for(i=0; i<pbmih->biHeight; i++) // RowData를 buff에서 순서대로 읽음
{
for(j=0 ; j < bpw; j++)
{
pRowData[bpw*i+j] = ((k+1)*buff[INDEX])/50.0;
INDEX++;
}
INDEX = INDEX + dummy_byte;
}
{
FILE* fp;
char namet[50]="";
sprintf(namet,"reverse%02d.bmp",k);
fp=fopen(namet,"wb");
fwrite(buff,1,54,fp);
fwrite(pRowData,1,buff_rowdata_size,fp);
fclose(fp);
}
}
return (buff_rowdata_size);
}
DWORD Mtel_BMP_TxtOut(BYTE *newname, BMFH *pbmfh, BMIH *pbmih, RGB *ppalette, BYTE *pRowData, DWORD color, DWORD rowdata_size)
{
FILE *fnew ;
DWORD i;
DWORD j;
DWORD y;
DWORD colorindex = 0;
DWORD rowdata_index = 0;
if( (fnew = fopen(newname, "w")) == NULL) //파일 열기 시도
{
fprintf(stderr, "New file open error");
return -1;
}
fprintf(fnew, "**** File Header Analysis ****\n");
fprintf(fnew, "File Type : %c%c\n", pbmfh->bfType,pbmfh->bfType >> 8);
fprintf(fnew, "File Size : %d byte\n", pbmfh->bfSize);
fprintf(fnew, "File OffsetBits : %d\n", pbmfh->bfOffBits);
fprintf(fnew, "\n");
fprintf(fnew, "**** BitMap Header Analysis ****\n");
fprintf(fnew, "Header Size : %d byte\n", pbmih->biSize);
fprintf(fnew, "Width : %d pixel\n", pbmih->biWidth);
fprintf(fnew, "Height : %d pixel\n", pbmih->biHeight);
fprintf(fnew, "BitCount : %d bpp(bits per pixels)\n", pbmih->biBitCount);
fprintf(fnew, "Size Image : %d byte\n", pbmih->biSizeImage);
fprintf(fnew, "ColorsUsed : %d\n", pbmih->biClrUsed);
fprintf(fnew, "Planes : %d\n", pbmih->biPlanes);
fprintf(fnew, "Comperssion : %d\n", pbmih->biCompression);
fprintf(fnew, "XpelsperMeter : %d dpi\n", pbmih->biXPelsPerMeter);
fprintf(fnew, "YPelsperMeter : %d dpi\n", pbmih->biYPelsPerMeter);
fprintf(fnew, "ColorsImportant : %d\n", pbmih->biClrImportant);
if(pbmih->biBitCount<24)
{
fprintf(fnew, "\n**** Color Palette Information ****\n");
fprintf(fnew, "INDEX \t R \t G \t B \n");
for(i=0; i < color ; i++)
{
fprintf(fnew, "0%.3X\t %.2X\t %.2X\t %.2X\t\n",
colorindex, (ppalette+i)->rgbRed, (ppalette+i)->rgbGreen, (ppalette+i)->rgbBlue);
colorindex++;
}
}
else
{
fprintf(fnew, "\n**** Color Palette Information ****\n");
fprintf(fnew, "Not Used Palette\n");
}
fprintf(fnew, "\n\t\t\t**** BitMap RowData Information ****\n\n");
for (j = 0; j < rowdata_size; j++)
{
if( j%16 == 0 )
{
fprintf(fnew,"\n");
rowdata_index += 16;
fprintf(fnew,"%.8X : ", rowdata_index);
}
fprintf(fnew, " %.2X ", pRowData[j]);
}
fclose(fnew);
return 0;
}
* C 에 옮겨서 보시면 지금보다 더 읽기 편하실 꺼라 생각됩니다.
음, 위 소스 파일은 C 로 bmp 파일을 읽어들여서 점점 이미지가 어두운 상태에서 밝아지게 변하면서
이미지가 연속적으로 출력되게 하고, bmp 이미지정보와 색들을 16 진수로 out.txt 에 나타내게 합니다.
(이미지를 180도 회전하게 하는 소스도 포함되어 있습니다)
이런 식으로 bmp 이미지에 적용할 수 있는 소스들을 더 얻을 수 있는 곳이 없을까요?
예를 들면 중심축을 기준으로 이미지를 회전하는 소스 같은것이 필요합니다.
알고 계시는 소스가 있으시거나, 참고할만한 사이트가 있으면 알려주시면 감사하겠습니다 (__)