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
댓글 달기