Solaris, HP-UX, windows 환경에서 실행한 결과가 틀린 문제에
글쓴이: caeman / 작성시간: 수, 2003/02/05 - 12:26오전
아래 소스 코드는 windows 흑백 BMP 파일을 읽어서
특정한 목적의 ASCII Text 파일을 만들어 내는 것 입니다.
Solaris, HP-UX, windows 환경에서 컴파일과 실행은 모두 잘되나
실행한 결과값이 상이합니다.
Solaris 환경에서만 실행한 결과값을 유효하게 사용할 수 있습니다.
OS에 따라 변화되는 테이터 형과 상수가 있는 것 같습니다.
이 코드를 windows 환경에서 제대로 사용하려면 어느 부분을
변경하여야 하는지 문의 드립니다.
/*-------------------------------------------- Program to produce ascii_geom file from a windows bitmap produces polygons over more than one line -------------------------------------------*/ #include <stdio.h> #include <stdlib.h> /* types */ typedef int BOOL; typedef unsigned char BYTE; typedef unsigned short int WORD; typedef unsigned long int DWORD; typedef struct { BYTE l; BYTE h; }UWORD; typedef struct { UWORD l; UWORD h; }UDWORD; typedef signed long int LONG; typedef struct { UWORD type; UDWORD size; UWORD reserved1; UWORD reserved2; UDWORD offbits; } BMPHEADER; typedef struct{ UDWORD size; UDWORD width; UDWORD height; UWORD planes; UWORD bitcount; UDWORD compression; UDWORD sizeimage; LONG biXPelsPerMeter; LONG biYPelsPerMeter; UDWORD biClrUsed; UDWORD biClrImportant; } BMPINFOHEADER; typedef struct { BYTE rgbBlue; BYTE rgbGreen; BYTE rgbRed; BYTE rgbReserved; } RGBQUAD; typedef struct { BMPINFOHEADER bmiheader; RGBQUAD bmicolors[1]; } BMPINFO; /* constants */ #define FALSE 0 #define TRUE !FALSE DWORD getDWORD( UDWORD dword) { DWORD llbyte =0; DWORD lhbyte =0; DWORD hlbyte =0; DWORD hhbyte =0; llbyte = (DWORD)(dword.l.l); lhbyte = (DWORD)(dword.l.h); hlbyte = (DWORD)(dword.h.l); hhbyte = (DWORD)(dword.h.h); return ((hhbyte<<24) | (hlbyte<<16) |(lhbyte <<8)|llbyte); } WORD getWORD( UWORD word) { WORD lowbyte =0; WORD highbyte =0; lowbyte = (WORD)word.l; highbyte = (WORD)word.h; highbyte = highbyte<<8; return (highbyte | lowbyte); } BOOL check_long_bit( int xpos, LONG data ) { LONG mask = 1; BOOL result; mask = mask <<(31-xpos); if((mask&data) ==0 ) result = FALSE; else result = TRUE; return result; } void write_ascii_data( FILE* outfptr, LONG* bits, DWORD width, DWORD height) { LONG xpos = 0; LONG ypos = 0; LONG lcount = 0; BOOL pixline = FALSE; LONG pixlinestart = 0; /* calculate the number of longs per line */ lcount = width /32 +1; for (ypos = 0;ypos < height;ypos++) { pixlinestart = 0; for (xpos = 0;xpos <width;xpos++) { if (check_long_bit(xpos%32,bits[lcount*ypos +xpos/32]) == FALSE) { if (pixline == FALSE) { pixlinestart = xpos; } pixline = TRUE; /*fprintf(stdout,"1");*/ } else { if(pixline == TRUE) fprintf(outfptr,"$$polygon( \"DRAWING\", ,[%.1f, %.1f, %.1f, %.1f, %.1f, %.1f, %.1f, %.1f, %.1f, %.1f]);\n", (float)pixlinestart, (float)ypos, (float)xpos, (float)ypos, (float)xpos, (float)ypos+1, (float)pixlinestart, (float)ypos+1, (float)pixlinestart, (float)ypos); /*endif*/ pixline = FALSE; /*fprintf(stdout,"0");*/ } } if(pixline == TRUE) fprintf(outfptr,"$$polygon( \"DRAWING\", ,[%.1f, %.1f, %.1f, %.1f, %.1f, %.1f, %.1f, %.1f, %.1f, %.1f]);\n", (float)pixlinestart, (float)ypos, (float)xpos, (float)ypos, (float)xpos, (float)ypos+1, (float)pixlinestart, (float)ypos+1, (float)pixlinestart, (float)ypos); pixline = FALSE; pixlinestart = 0; fprintf(stdout,"."); /*fprintf(stdout,"\n");*/ } fprintf(stdout,"\n"); } void process_files (FILE* infptr, FILE* outfptr) { BMPHEADER header; BMPINFO info; long int longwidthcount; long int longcount,in; LONG* bits; /* read the bitmap file header */ if ( fread(&header,sizeof(BMPHEADER),1,infptr) != 1) { fprintf(stderr,"Error : could not read file header\n"); exit(1); } else { printf("Input file size : %ld bytes\n",getDWORD(header.size)); } /* read the bitmap info */ if ( fread(&info,sizeof(BMPINFO),1,infptr) != 1) { fprintf(stderr,"Error : could not read bitmap info\n"); exit(1); } else { printf("Bitmap width %ld height %ld \n",getDWORD(info.bmiheader.width), getDWORD(info.bmiheader.height)); /* Check if the image is monochrome */ if(getDWORD(info.bmiheader.compression) != 0 || getWORD(info.bmiheader.bitcount) != 1) { fprintf(stderr,"Error : The image is not monochrome\n"); exit(1); } } /* set the file pointer to the start of the pixel data */ fseek(infptr,getDWORD(header.offbits),0); /* calculate the number of longs per line */ longwidthcount =getDWORD(info.bmiheader.width) /32 +1; /* calculate the number of LONG's for the whole image */ longcount = longwidthcount * getDWORD(info.bmiheader.height); /* allocate the matrix of longs for the off screen bitmap */ bits = (LONG*)malloc((size_t)(sizeof(LONG)*longcount)); if (bits == NULL) { fprintf(stderr,"Error : The allocation for off screen bitmap failed"); exit(1); } /* now read the data into the offscreen bitmap */ if(fread(bits,sizeof(LONG),longcount,infptr) != longcount) { fprintf(stderr,"Error : Could not read all of the data"); exit(1); } /*for (in = 0;in<longcount;in++) fprintf(stdout,"%08lX ",bits[in]); */ /* now convert and write the data ti ascii geom file */ write_ascii_data(outfptr,bits,getDWORD(info.bmiheader.width),getDWORD(info.bmiheader.height)); } int main (int argc, char** argv) { char* infname = "bmp2asc.bmp"; char* outfname = "geom.asc"; FILE* infptr = NULL; FILE* outfptr = NULL; fprintf(stdout,"BMP2ASC version 1.0 (c) 1997 Chad Williams\n"); fprintf(stdout,"Windows Bitmap to Ascii geom converter\n"); /* open the input file for reading */ infptr = fopen(infname,"r"); if (infptr == NULL) { fprintf(stderr,"The file %s cannot be read for input\n",infname); exit(1); } /*open the output file for writing*/ outfptr = fopen(outfname,"w"); if (outfptr == NULL) { fprintf(stderr,"The file %s cannot be read for output\n",outfname); exit(1); } /* write initial generic code */ fprintf(outfptr,"$$lock_windows(@on);\n"); fprintf(outfptr,"$$create_generic_part(\"geom\");\n"); fprintf(outfptr,"$$page(0.0, 0.0, 0.0, @mils, 0.0, 0.0, [0.0,0.0,'E$geom'] );\n"); fprintf(outfptr,"$$point_mode(@vertex);\n"); fprintf(outfptr,"$$template_line_style( @Solid );\n"); /* convert the data to ascii geom statments */ process_files(infptr,outfptr); /* if the input file was opened close it */ if (infptr != NULL) { fclose(infptr); } /* if the output file was opened close it */ if (outfptr != NULL) { fclose(outfptr); } return 0; }
Forums:
ㅇㅇㅇ
OS 차이가 아니라. CPU 차이이지 않나요???????
hi ~
endian문제
Solaris는 Big endian이고 x86은 little endian입니다.
low와 high바이트를 얻는 루틴을 매크로등으로 고치셔야할 것으로 생각됩니다.
온갖 참된 삶은 만남이다 --Martin Buber
댓글 달기