473,386 Members | 1,803 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,386 software developers and data experts.

Problem Reading Bmp's ..

Hi all,

Im trying to read a 24bit bmp with fread, and i have some problems.. I
want to read the whole structure in one time, but i dont know why, it
only reads the first member well..

I have two questions..

1- why if i change fread(bmp1, sizeof(bmp1), 1, fin); to fread(bmp1,
sizeof(struct bmp), 1, fin); i have a Segment violation ??

2- can i read the whole structure in one time ?? ( i can read the
structure well if i read it member by member)
Code>>
#include <stdio.h>
#include <stdlib.h>

typedef unsigned char BYTE,uc;
typedef unsigned short WORD,us;
typedef unsigned long DWORD,ul;
typedef unsigned long LONG;

struct bmp{

WORD FileType; /* File type, always 4D42h ("BM") */
DWORD FileSize; /* Size of the file in bytes */
WORD Reserved1; /* Always 0 */
WORD Reserved2; /* Always 0 */
DWORD BitmapOffset; /* Starting position of image data in bytes
*/
DWORD Size; /* Size of this header in bytes */
LONG Width; /* Image width in pixels */
LONG Height; /* Image height in pixels */
WORD Planes; /* Number of color planes */
WORD BitsPerPixel; /* Number of bits per pixel */
DWORD Compression; /* Compression methods used */
DWORD SizeOfBitmap; /* Size of bitmap in bytes */
LONG HorzResolution; /* Horizontal resolution in pixels per
meter */
LONG VertResolution; /* Vertical resolution in pixels per meter
*/
DWORD ColorsUsed; /* Number of colors in the image */
DWORD ColorsImportant; /* Minimum number of important colors */
};

int main(){

struct bmp *bmp1;

ul i;
FILE *fin;

fin=fopen("1.bmp","rb");
if (fin == NULL) return 0;
fread(bmp1, sizeof(bmp1), 1, fin);
printf("\n Propiedades de la imagen\n");
printf("
__________________________________________________ ____________\n");
printf("\n Tipo de fichero: %d\n",bmp1->FileType);
printf("\n Tamaño del fichero en bytes: %d\n",bmp1->FileSize);
printf("\n Zona reservada: %d\n",bmp1-Reserved1);
printf("\n Zona reservada: %d\n",bmp1-Reserved2);
printf("\n Offset hasta el mapa de bits:%d\n",bmp1-
>BitmapOffset);
printf("\n Tamaño de la cabecera: %d\n",bmp1->Size);
printf("\n Ancho de la imagen: %d \n",bmp1->Width);
printf("\n Altura de la imagen: %d \n",bmp1->Height);
printf("\n Número de planos: %d \n",bmp1->Planes);
printf("\n Bits por pixel: %d \n",bmp1->BitsPerPixel);
printf("\n Compresión: %d \n",bmp1->Compression);
printf("\n Tamaño de la imagen en bytes: %d \n",bmp1-
>SizeOfBitmap);
printf("\n Resolución horizontal: %d \n",bmp1->HorzResolution);
printf("\n Resolución vertical: %d \n",bmp1->VertResolution);
printf("\n Tamaño de la paleta: %d \n",bmp1->ColorsUsed);
printf("\n Colores importantes: %d \n\n",bmp1->ColorsImportant);

unsigned char *puntero=malloc(sizeof(uc)*((bmp1->SizeOfBitmap)*3));


FILE *fout;
fout=fopen("2.bmp","wb");

fwrite(bmp1,sizeof(struct bmp),1,fout);
fclose(fin);
fclose(fout);
free(puntero);

};

__________________________________________

Console Result>>


Propiedades de la imagen
__________________________________________________ ____________

Tipo de fichero: 19778 ***** (this is BM, its ok)

Tamaño del fichero en bytes: -1208460616 ******** ( ???)

Zona reservada: 6944 ********* ( ??? )

Zona reservada: 47097

Offset hasta el mapa de bits:-1209676762

Tamaño de la cabecera: -1209347184

Ancho de la imagen: -1209676730

Altura de la imagen: -1209676714

Número de planos: 52326

Bits por pixel: 47077

Compresión: -1209676682

Tamaño de la imagen en bytes: -1209676666

Resolución horizontal: 0

Resolución vertical: 0

Tamaño de la paleta: 0

Colores importantes: 0

May 12 '07 #1
16 3708

<Jm************@gmail.comwrote in message
news:11**********************@o5g2000hsb.googlegro ups.com...
>
Im trying to read a 24bit bmp with fread, and i have some problems.. I
want to read the whole structure in one time, but i dont know why, it
only reads the first member well..
If you declare a structure and fred it it might match up and it might not.
It will also break on a different compiler.
The way to treat a binary file format is to declare functions that load the
fields byte by byte from the stream and reassemble them. For instance image
width is a 32 bit integer, I think little-endian.

Wrap up the entire read into one function. Probably you only want image
dimensions and raster data. However you might not want the bgr-padding
format Microsoft use, and there is no reason you should return the raster in
that order.
--
Free games and programming goodies.
http://www.personal.leeds.ac.uk/~bgy1mm

May 13 '07 #2
The way to treat a binary file format is to declare functions that load the
fields byte by byte from the stream and reassemble them. For instance image
width is a 32 bit integer, I think little-endian.

Wrap up the entire read into one function. Probably you only want image
dimensions and raster data. However you might not want the bgr-padding
format Microsoft use, and there is no reason you should return the raster in
that order.
I use gcc.. so.. do you think its better to read it member by member
or there is something to fix it?

Thanks

May 13 '07 #3
Here its a sample of my old code.. do you mean something like this?
can i fix the problem with #pragma or something like that? Thanks

CODE:

int openBmp(char *nombre,unsigned char *puntero) {

struct bmp *bmp1;
ul i;
FILE *fin;

fin=fopen("1","rb");
if (fin == NULL) return 0;
fopen(&bmp1->FileType, sizeof(bmp1->FileType), 1, fout);
fopen(&bmp1->FileSize, sizeof(bmp1->FileSize), 1, fout);
fopen(&bmp1->Reserved1, sizeof(bmp1->Reserved1), 1, fout);
fopen(&bmp1->Reserved2, sizeof(bmp1->Reserved2), 1, fout);
fopen(&bmp1->BitmapOffset, sizeof(bmp1->BitmapOffset), 1, fout);
fopen(&bmp1->Size, sizeof(bmp1->Size), 1, fout);
fopen(&bmp1->Width, sizeof(bmp1->Width), 1, fout);
fopen(&bmp1->Height, sizeof(bmp1->Height), 1, fout);
fopen(&bmp1->Planes, sizeof(bmp1->Planes), 1, fout);
fopen(&bmp1->BitsPerPixel, sizeof(bmp1->BitsPerPixel), 1, fout);
fopen(&bmp1->Compression, sizeof(bmp1->Compression), 1, fout);
fopen(&bmp1->SizeOfBitmap, sizeof(bmp1->SizeOfBitmap), 1, fout);
fopen(&bmp1->HorzResolution, sizeof(bmp1->HorzResolution), 1, fout);
fopen(&bmp1->VertResolution, sizeof(bmp1->VertResolution), 1, fout);
fopen(&bmp1->ColorsUsed, sizeof(bmp1->ColorsUsed), 1, fout);
fopen(&bmp1->ColorsImportant, sizeof(bmp1->ColorsImportant), 1, fout);
puntero=malloc(sizeof(uc)*(SizeOfBitmap*3));
for (i=0;i<(bmp1->SizeOfBitmap*3);i++) {
fread(puntero,sizeof(uc),1,fin);
};

fclose(fin);

};

May 13 '07 #4
FREAD INSTEAD OF FOPEN ;)

May 13 '07 #5

<Jm************@gmail.comwrote in message
news:11*********************@o5g2000hsb.googlegrou ps.com...
Here its a sample of my old code.. do you mean something like this?
can i fix the problem with #pragma or something like that? Thanks

CODE:

int openBmp(char *nombre,unsigned char *puntero) {

struct bmp *bmp1;
ul i;
FILE *fin;

fin=fopen("1","rb");
if (fin == NULL) return 0;
fopen(&bmp1->FileType, sizeof(bmp1->FileType), 1, fout);
fopen(&bmp1->FileSize, sizeof(bmp1->FileSize), 1, fout);
fopen(&bmp1->Reserved1, sizeof(bmp1->Reserved1), 1, fout);
fopen(&bmp1->Reserved2, sizeof(bmp1->Reserved2), 1, fout);
fopen(&bmp1->BitmapOffset, sizeof(bmp1->BitmapOffset), 1, fout);
fopen(&bmp1->Size, sizeof(bmp1->Size), 1, fout);
fopen(&bmp1->Width, sizeof(bmp1->Width), 1, fout);
fopen(&bmp1->Height, sizeof(bmp1->Height), 1, fout);
fopen(&bmp1->Planes, sizeof(bmp1->Planes), 1, fout);
fopen(&bmp1->BitsPerPixel, sizeof(bmp1->BitsPerPixel), 1, fout);
fopen(&bmp1->Compression, sizeof(bmp1->Compression), 1, fout);
fopen(&bmp1->SizeOfBitmap, sizeof(bmp1->SizeOfBitmap), 1, fout);
fopen(&bmp1->HorzResolution, sizeof(bmp1->HorzResolution), 1, fout);
fopen(&bmp1->VertResolution, sizeof(bmp1->VertResolution), 1, fout);
fopen(&bmp1->ColorsUsed, sizeof(bmp1->ColorsUsed), 1, fout);
fopen(&bmp1->ColorsImportant, sizeof(bmp1->ColorsImportant), 1, fout);
puntero=malloc(sizeof(uc)*(SizeOfBitmap*3));
for (i=0;i<(bmp1->SizeOfBitmap*3);i++) {
fread(puntero,sizeof(uc),1,fin);
};

fclose(fin);

};
Eek.
No.
Like this

/*
We want to load an image as a raster. Probably we want rgb values, but we
can easily change to bga-dummy, or an array of COLORREFs if required just be
altering the code a bit.
The code is a unit. Take the name of the .bmp file, return the raster and
the image dimensions.
On error return NULL. If you need more error information then pass in
another integer. However generally you just need to know if the function
failed or succeeded.
*/

unsigned char *loadbmp(const char *fname, int *width, int *height)
{
FILE *fp;
int err;
unsigned char *answer;
/* open file in binary mode */
fp = fopen(fname, "rb");
if(!fp)
return 0;

/* get all the information we need for the header */
err = loadheader(fp, &width, &height);

/*
in this code we allocate memory for the raster, and load it.
we have to be careful to clean up if we encounter error condtions.
*/
if(err == 0)
{
answer = malloc(width * height * 3);
if(answer)
err = loadraster(fp, answer, width, height);
if(err != 0)
{
free(answer);
answer = 0;
}
}
else
answer = 0;

fclose(fp);
}

/*
load the header information. Probably all we need is the width and the
height,
but you might want other fields like image physical size.
*/
int loadheader(FILE *fp, int *width, int *height)
{
int i;
/* skip a bit of useless information - number made up */
for(i=0;i<123;i++)
fgetc(fp);
/* load width - I think it is a 32 bit little endian. Note this code
could
be tightened up a bit */
*width = fgetc();
*width += fgetc() << 8;
*width += fgetc() << 16;
*width += fgetc() << 24;
/* same for height */
*height = fgetc();
*height += fgetc() << 8;
*height += fgetc() << 16;
*height+= fgetc() << 24;
/* skip trailing useless information */
for(i=0;i<123;i++)
fgetc(fp);

/* now sanity test width and height, also you might want to check the
"useless" fields for integrity */
if(*width <= 0 || *width 16000)
return -1;
return 0
}

/*
now load the raster information into our buffer.
*/
int loadraster(FILE *fp, unsigned char *out, int width, int height)
{
int i;
int ii;
unsigned char red, green, blue;

for(i=0;i<height;i++)
{
for(ii=0;ii<width;ii++)
{
blue = fgetc(fp);
green = fgetc(fp);
red = fgetc(fp);
fgetc(fp); /* skip padding byte */
*out++ = red;
*out++ = green;
*out++ = blue;
}
/* might need to skip a few bytes at end of line */
}
/* if we ran out of data fail */
if(feof(fp))
return -1;
return 0;
}

This is skeleton code. It won't work exactly as typed in because I can't
remember all the details of the BMP format. Also I haven't tried compiling
it. It is simply intended to show you how to approach the problem and to
provide a framework.
--
Free games and programming goodies.
http://www.personal.leeds.ac.uk/~bgy1mm

May 13 '07 #6
Jm************@gmail.com wrote:
Im trying to read a 24bit bmp with fread, and i have some problems.. I
want to read the whole structure in one time, but i dont know why, it
only reads the first member well..

I have two questions..

1- why if i change fread(bmp1, sizeof(bmp1), 1, fin); to fread(bmp1,
sizeof(struct bmp), 1, fin); i have a Segment violation ??
bmp1 is a pointer, and sizeof( bmp1 ) is the size of the pointer, not
the structure it points to.

sizeof( bmp1 ) != sizeof( struct bmp )
sizeof( *bmp1 ) == sizeof( struct bmp )
sizeof( bmp1 ) == sizeof( struct bmp * )

You get a segment fault because you haven't initialized bmp1. You don't
allocate any memory for it to point to.

struct bmp *bmp1;
bmp1 = malloc( sizeof *bmp1 );
if ( !bmp1 ) ... /* malloc() failed */

That only the second version leads to a segment fault is accidental.
Both of them might, or neither of them might.
2- can i read the whole structure in one time ?? ( i can read the
structure well if i read it member by member)
The answer to this is complicated.

You probably can't read your struct bmp all at once, as it is currently
defined. You can modify your struct bmp so that it will work, but you
should only do this with the understanding that it's not, in general,
the best way to approach reading binary files.
struct bmp{

WORD FileType; /* File type, always 4D42h ("BM") */
DWORD FileSize; /* Size of the file in bytes */
The second field is a DWORD, which is typically aligned on a 4-byte
boundary, meaning that the compiler will insert 2 bytes of padding after
the first field. This padding doesn't exist in the file, so your entire
structure will be misaligned with the contents of the file.

If you remove the first field, however, it's pretty likely that you will
be able to read in the rest of the structure in one call to fread(),
after reading the first two bytes separately.
unsigned char *puntero=malloc(sizeof(uc)*((bmp1->SizeOfBitmap)*3));
The extra parentheses are unnecessary. You can write

sizeof uc * bmp1->SizeOfBitmap * 3

Unless you're using a compiler that supports C99, or writing in C++
rather than C, you can't declare puntero at this point in the code.

If "uc" means "unsigned char", this will always be 1. You don't have to
multiply by this.

SizeOfBitmap will either contain the number of bytes required to hold
all three color channels, so that you don't have to multiply by 3, or it
will (very often for 24-bit BMPs) contain 0, so that you must calculate
the storage requirement some other way.

In my BMP reading code, I find the storage requirement by subtracting
the header size from the file size. I also use the BITMAPINFOHEADER
structure provided by the Win32 headers, rather than creating my own
struct bmp.

- Ernie http://home.comcast.net/~erniew
May 13 '07 #7
Malcolm McLean wrote, On 13/05/07 01:59:
>
<Jm************@gmail.comwrote in message
news:11*********************@o5g2000hsb.googlegrou ps.com...
>Here its a sample of my old code.. do you mean something like this?
can i fix the problem with #pragma or something like that? Thanks
<snip>
Eek.
No.
Like this

/*
We want to load an image as a raster. Probably we want rgb values, but
we can easily change to bga-dummy, or an array of COLORREFs if required
just be altering the code a bit.
The code is a unit. Take the name of the .bmp file, return the raster
and the image dimensions.
On error return NULL. If you need more error information then pass in
another integer. However generally you just need to know if the function
failed or succeeded.
*/

unsigned char *loadbmp(const char *fname, int *width, int *height)
{
FILE *fp;
int err;
unsigned char *answer;
/* open file in binary mode */
fp = fopen(fname, "rb");
if(!fp)
return 0;

/* get all the information we need for the header */
err = loadheader(fp, &width, &height);
Always make sure you have a prototype in scope for a function before
calling it. Then the compiler will tell you that you are passing values
of the wrong type in the above line.
/*
in this code we allocate memory for the raster, and load it.
we have to be careful to clean up if we encounter error condtions.
*/
if(err == 0)
{
answer = malloc(width * height * 3);
if(answer)
err = loadraster(fp, answer, width, height);
It will tell you about a type mismatch here as well.
if(err != 0)
{
free(answer);
answer = 0;
}
}
else
answer = 0;

fclose(fp);
Having defined the function as returning an unsigned char* would not
returning one be a good idea? Possibly return answer since otherwise you
have lost the memory?
}

/*
load the header information. Probably all we need is the width and the
height,
but you might want other fields like image physical size.
*/
int loadheader(FILE *fp, int *width, int *height)
{
int i;
/* skip a bit of useless information - number made up */
for(i=0;i<123;i++)
fgetc(fp);
/* load width - I think it is a 32 bit little endian. Note this code
could
be tightened up a bit */
*width = fgetc();
*width += fgetc() << 8;
*width += fgetc() << 16;
*width += fgetc() << 24;
You should document your assumption that int is at least 32 bits (since
the C standard does not guarantee it) or use a type that is guaranteed
to e large enough.
/* same for height */
*height = fgetc();
*height += fgetc() << 8;
*height += fgetc() << 16;
*height+= fgetc() << 24;
/* skip trailing useless information */
for(i=0;i<123;i++)
fgetc(fp);

/* now sanity test width and height, also you might want to check the
"useless" fields for integrity */
if(*width <= 0 || *width 16000)
return -1;
You should probably be using unsigned types rather than signed types,
since that is proably how the image format is defined. Also, a lot of
cameras produce images larger than that.
return 0
}

/*
now load the raster information into our buffer.
*/
int loadraster(FILE *fp, unsigned char *out, int width, int height)
{
int i;
int ii;
unsigned char red, green, blue;

for(i=0;i<height;i++)
{
for(ii=0;ii<width;ii++)
{
blue = fgetc(fp);
green = fgetc(fp);
red = fgetc(fp);
fgetc(fp); /* skip padding byte */
*out++ = red;
*out++ = green;
*out++ = blue;
}
/* might need to skip a few bytes at end of line */
}
/* if we ran out of data fail */
if(feof(fp))
return -1;
return 0;
}

This is skeleton code. It won't work exactly as typed in because I can't
remember all the details of the BMP format. Also I haven't tried
compiling it. It is simply intended to show you how to approach the
problem and to provide a framework.
Even with a framework you should avoid the obvious mistakes you made
here like passing incorrect parameter types. That is not going to help
someone who is learning.
--
Flash Gordon
May 13 '07 #8

"Flash Gordon" <sp**@flash-gordon.me.ukwrote in message
news:6o************@news.flash-gordon.me.uk...
Malcolm McLean wrote, On 13/05/07 01:59:
>>
<Jm************@gmail.comwrote in message
news:11*********************@o5g2000hsb.googlegro ups.com...
>>Here its a sample of my old code.. do you mean something like this?
can i fix the problem with #pragma or something like that? Thanks

<snip>
>Eek.
No.
Like this

/*
We want to load an image as a raster. Probably we want rgb values, but
we can easily change to bga-dummy, or an array of COLORREFs if required
just be altering the code a bit.
The code is a unit. Take the name of the .bmp file, return the raster and
the image dimensions.
On error return NULL. If you need more error information then pass in
another integer. However generally you just need to know if the function
failed or succeeded.
*/

unsigned char *loadbmp(const char *fname, int *width, int *height)
{
FILE *fp;
int err;
unsigned char *answer;
/* open file in binary mode */
fp = fopen(fname, "rb");
if(!fp)
return 0;

/* get all the information we need for the header */
err = loadheader(fp, &width, &height);

Always make sure you have a prototype in scope for a function before
calling it. Then the compiler will tell you that you are passing values of
the wrong type in the above line.
> /*
in this code we allocate memory for the raster, and load it.
we have to be careful to clean up if we encounter error condtions.
*/
if(err == 0)
{
answer = malloc(width * height * 3);
if(answer)
err = loadraster(fp, answer, width, height);

It will tell you about a type mismatch here as well.
> if(err != 0)
{
free(answer);
answer = 0;
}
}
else
answer = 0;

fclose(fp);

Having defined the function as returning an unsigned char* would not
returning one be a good idea? Possibly return answer since otherwise you
have lost the memory?
>}

/*
load the header information. Probably all we need is the width and the
height,
but you might want other fields like image physical size.
*/
int loadheader(FILE *fp, int *width, int *height)
{
int i;
/* skip a bit of useless information - number made up */
for(i=0;i<123;i++)
fgetc(fp);
/* load width - I think it is a 32 bit little endian. Note this code
could
be tightened up a bit */
*width = fgetc();
*width += fgetc() << 8;
*width += fgetc() << 16;
*width += fgetc() << 24;

You should document your assumption that int is at least 32 bits (since
the C standard does not guarantee it) or use a type that is guaranteed to
e large enough.
>/* same for height */
*height = fgetc();
*height += fgetc() << 8;
*height += fgetc() << 16;
*height+= fgetc() << 24;
/* skip trailing useless information */
for(i=0;i<123;i++)
fgetc(fp);

/* now sanity test width and height, also you might want to check the
"useless" fields for integrity */
if(*width <= 0 || *width 16000)
return -1;

You should probably be using unsigned types rather than signed types,
since that is proably how the image format is defined. Also, a lot of
cameras produce images larger than that.
> return 0
}

/*
now load the raster information into our buffer.
*/
int loadraster(FILE *fp, unsigned char *out, int width, int height)
{
int i;
int ii;
unsigned char red, green, blue;

for(i=0;i<height;i++)
{
for(ii=0;ii<width;ii++)
{
blue = fgetc(fp);
green = fgetc(fp);
red = fgetc(fp);
fgetc(fp); /* skip padding byte */
*out++ = red;
*out++ = green;
*out++ = blue;
}
/* might need to skip a few bytes at end of line */
}
/* if we ran out of data fail */
if(feof(fp))
return -1;
return 0;
}

This is skeleton code. It won't work exactly as typed in because I can't
remember all the details of the BMP format. Also I haven't tried
compiling it. It is simply intended to show you how to approach the
problem and to provide a framework.

Even with a framework you should avoid the obvious mistakes you made here
like passing incorrect parameter types. That is not going to help someone
who is learning.
It was a mistake to write so much skeleton code without compiling it. I
agree.

--
Free games and programming goodies.
http://www.personal.leeds.ac.uk/~bgy1mm

May 13 '07 #9
<Jm************@gmail.comha scritto nel messaggio
news:11**********************@o5g2000hsb.googlegro ups.com...
Hi all,

Im trying to read a 24bit bmp with fread, and i have some problems.. I
want to read the whole structure in one time, but i dont know why, it
only reads the first member well..

I have two questions..

1- why if i change fread(bmp1, sizeof(bmp1), 1, fin); to fread(bmp1,
sizeof(struct bmp), 1, fin); i have a Segment violation ??
See Ernie Wright's answer.
2- can i read the whole structure in one time ?? ( i can read the
structure well if i read it member by member)
[code snipped]

Portably you don't. You dont know wheter there is any padding in
the struct. Even if you read it member by member beware of this:
1. On some other systems, unsigned char, unsigned short, unsigned
long might have different sizes. If you have a C99 compiler, use
uint8_t, uint16_t and uint_32t found in <inttypes.hand
<stdint.h>.
2. Different machines have different endiannesses. The best
solution I can see, unfortunately (other than the "twisty maze of
#ifdef's" approach) is:
for (i=0; i<4; i++) {
n <<= CHAR_BIT;
n |= getchar();
}
(obviously this is just the idea, don't copy and paste it).

If you want to do things portably, use the ppm format, it is much
easier. It looks like that

P3
# comments
640 480
255
0 0 0 0 0 0 1 1 1...
(P3 is the header, 640 and 480 are the resolution, 255 is the depth
and the next are triples showing colors (0 0 0 = #000000, 0 0 1 =
#000001... 255 255 255 = #FFFFFF).

Or:

P6
# comments
640 480
255
<binary data>

e.g.
struct Pixel {unsigned char Red, Green, Blue} p;
putc(p.Red, file); putc(p.Green, file); putc(p.Blue, file);
May 13 '07 #10
On May 13, 1:25 am, "Jm.GlezdeRu...@gmail.com"
<Jm.GlezdeRu...@gmail.comwrote:
I use gcc.. so.. do you think its better to read it member by member
or there is something to fix it?
First you have to make it clear to yourself what the data format of
that file actually is.

You have a struct definition, and the data format of the file is that
struct definition, compiled with one specific version of some old
Microsoft compiler for one specific processor. So forget about the
struct. What you have in the file is a sequence of bytes. Where you
have a "WORD" in that struct, what you actually have is two unsigned
eight bit chars, with the least significant one stored first.

So what you can do: Leave the struct as it is. Write a function to
read the struct from a file; you might also write a function to write
it to a file. In that function: Count exactly how many bytes that
struct has (when compiled with that version of the Microsoft
compiler). It is _not_ sizeof (struct), because that will tell you the
size on _your_ compiler, but you want the size on a _MS_ compiler.
Define an array of unsigned char with exactly that size and read it.
Then if you have a struct member that is for example a "WORD" starting
at offset 8, you set the value to (a [8]) + (a [9] << 8). That will
read the data portably on any implementation.

May 13 '07 #11
Thanks all, many interesting things in all these posts. i think Ernie
Wright has the clue about the structure problem.. Ive read something
like that in other posts, but i didnt understood very well ..
>>The second field is a DWORD, which is typically aligned on a 4-byte
boundary, meaning that the compiler will insert 2 bytes of padding after
the first field. This padding doesn't exist in the file, so your entire
structure will be misaligned with the contents of the file.

I will post the new code version, trying to jump the first member. But
why reading member by member it works fine??

Thanks all -

May 13 '07 #12
Malcolm McLean wrote:
>
.... snip ...
>
It was a mistake to write so much skeleton code without compiling
it. I agree.
In todays world you should normally compile a file every few
minutes. It normally takes a key stroke to switch windows, an up
arrow to restore the compile command, and bang return.

--
<http://www.cs.auckland.ac.nz/~pgut001/pubs/vista_cost.txt>
<http://www.securityfocus.com/columnists/423>
<http://www.aaxnet.com/editor/edit043.html>
<http://kadaitcha.cx/vista/dogsbreakfast/index.html>
cbfalconer at maineline dot net

--
Posted via a free Usenet account from http://www.teranews.com

May 13 '07 #13
On May 13, 1:27 am, Flash Gordon <s...@flash-gordon.me.ukwrote:
Malcolm McLean wrote, On 13/05/07 01:59:
<Jm.GlezdeRu...@gmail.comwrote in message
news:11*********************@o5g2000hsb.googlegrou ps.com...
Here its a sample of my old code.. do you mean something like this?
can i fix the problem with #pragma or something like that? Thanks

<snip>
Eek.
No.
Like this
/*
We want to load an image as a raster. Probably we want rgb values, but
we can easily change to bga-dummy, or an array of COLORREFs if required
just be altering the code a bit.
The code is a unit. Take the name of the .bmp file, return the raster
and the image dimensions.
On error return NULL. If you need more error information then pass in
another integer. However generally you just need to know if the function
failed or succeeded.
*/
unsigned char *loadbmp(const char *fname, int *width, int *height)
{
FILE *fp;
int err;
unsigned char *answer;
/* open file in binary mode */
fp = fopen(fname, "rb");
if(!fp)
return 0;
/* get all the information we need for the header */
err = loadheader(fp, &width, &height);

Always make sure you have a prototype in scope for a function before
calling it. Then the compiler will tell you that you are passing values
of the wrong type in the above line.
/*
in this code we allocate memory for the raster, and load it.
we have to be careful to clean up if we encounter error condtions.
*/
if(err == 0)
{
answer = malloc(width * height * 3);
if(answer)
err = loadraster(fp, answer, width, height);

It will tell you about a type mismatch here as well.
if(err != 0)
{
free(answer);
answer = 0;
}
}
else
answer = 0;
fclose(fp);

Having defined the function as returning an unsigned char* would not
returning one be a good idea? Possibly return answer since otherwise you
have lost the memory?
I don't understand the comment Flash made. Can someone please
elaborate a bit more on this?

Chad

May 13 '07 #14
On May 13, 3:56 pm, Chad <cdal...@gmail.comwrote:
On May 13, 1:27 am, Flash Gordon <s...@flash-gordon.me.ukwrote:
Malcolm McLean wrote, On 13/05/07 01:59:
<Jm.GlezdeRu...@gmail.comwrote in message
>news:11*********************@o5g2000hsb.googlegro ups.com...
>Here its a sample of my old code.. do you mean something like this?
>can i fix the problem with #pragma or something like that? Thanks
<snip>
Eek.
No.
Like this
/*
We want to load an image as a raster. Probably we want rgb values, but
we can easily change to bga-dummy, or an array of COLORREFs if required
just be altering the code a bit.
The code is a unit. Take the name of the .bmp file, return the raster
and the image dimensions.
On error return NULL. If you need more error information then pass in
another integer. However generally you just need to know if the function
failed or succeeded.
*/
unsigned char *loadbmp(const char *fname, int *width, int *height)
{
FILE *fp;
int err;
unsigned char *answer;
/* open file in binary mode */
fp = fopen(fname, "rb");
if(!fp)
return 0;
/* get all the information we need for the header */
err = loadheader(fp, &width, &height);
Always make sure you have a prototype in scope for a function before
calling it. Then the compiler will tell you that you are passing values
of the wrong type in the above line.
/*
in this code we allocate memory for the raster, and load it.
we have to be careful to clean up if we encounter error condtions.
*/
if(err == 0)
{
answer = malloc(width * height * 3);
if(answer)
err = loadraster(fp, answer, width, height);
It will tell you about a type mismatch here as well.
if(err != 0)
{
free(answer);
answer = 0;
}
}
else
answer = 0;
fclose(fp);
Having defined the function as returning an unsigned char* would not
returning one be a good idea? Possibly return answer since otherwise you
have lost the memory?
The part I'm drawing a blank on is

"Having defined the function as returning an unsigned char* would not
returning one be a good idea? Possibly return answer since otherwise
you
have lost the memory?"
May 13 '07 #15
I wrote:
>The second field is a DWORD, which is typically aligned on a 4-byte
boundary, meaning that the compiler will insert 2 bytes of padding
after the first field. This padding doesn't exist in the file, so
your entire structure will be misaligned with the contents of the
file.
Jm************@gmail.com wrote:
Thanks all, many interesting things in all these posts. i think Ernie
Wright has the clue about the structure problem.. Ive read something
like that in other posts, but i didnt understood very well ..
The first few bytes of a BMP file look like this:

byte contents
0 WORD FileType; /* File type, always 4D42h ("BM") */
1 :
2 DWORD FileSize; /* Size of the file in bytes */
3 :
4 :
5 :
6 WORD Reserved1; /* Always 0 */
7 :
8 WORD Reserved2; /* Always 0 */
9 :
...

In particular, the FileSize field begins at an offset of 2 bytes.

But when the compiler reserves storage for your structure, it will
usually add padding bytes:

byte contents
0 WORD FileType; /* File type, always 4D42h ("BM") */
1 :
2 ***** pad byte inserted by the compiler *****
3 ***** pad byte inserted by the compiler *****
4 DWORD FileSize; /* Size of the file in bytes */
5 :
6 :
7 :
8 WORD Reserved1; /* Always 0 */
9 :
10 WORD Reserved2; /* Always 0 */
11 :
...

Notice that the compiler put FileSize at an offset of 4 rather than 2,
and added 2 bytes of padding before it.

The layout of your structure in memory therefore doesn't match the
layout of the file. You'll also find that sizeof struct bmp is
(probably) 56 rather than 54.

The compiler does this in order to get the FileSize member to begin at
an offset that's a multiple of 4. In general, the most common alignment
puts structure members that are n bytes long at offsets divisible by n.

Some computers will actually crash if the compiler doesn't do this. On
most others, misaligned access is merely very slow.
I will post the new code version, trying to jump the first member. But
why reading member by member it works fine??
This is one reason that reading one member at a time, or better still,
one byte at a time, is the more robust and portable way to read a binary
file. You don't have to rely on the compiler laying out a structure in
memory in a way that exactly matches the layout in the file.

- Ernie http://home.comcast.net/~erniew
May 14 '07 #16
Chad wrote:
>Flash Gordon wrote:
>>Malcolm McLean wrote:
.... snip ...
>>>
unsigned char *loadbmp(const char *fname, int *width, int *height)
{
FILE *fp;
int err;
unsigned char *answer;
/* open file in binary mode */
fp = fopen(fname, "rb");
if(!fp)
return 0;
/* get all the information we need for the header */
err = loadheader(fp, &width, &height);
/*
in this code we allocate memory for the raster, and load it.
we have to be careful to clean up if we encounter error condtions.
*/
if(err == 0)
{
answer = malloc(width * height * 3);
if(answer)
err = loadraster(fp, answer, width, height);
if(err != 0)
{
free(answer);
answer = 0;
}
}
else
answer = 0;
fclose(fp);
}
>>>
Having defined the function as returning an unsigned char* would
not returning one be a good idea? Possibly return answer since
otherwise you have lost the memory?

The part I'm drawing a blank on is

"Having defined the function as returning an unsigned char* would
not returning one be a good idea? Possibly return answer since
otherwise you have lost the memory?"
Why? I don't see that function returning anything.

--
<http://www.cs.auckland.ac.nz/~pgut001/pubs/vista_cost.txt>
<http://www.securityfocus.com/columnists/423>
<http://www.aaxnet.com/editor/edit043.html>
<http://kadaitcha.cx/vista/dogsbreakfast/index.html>
cbfalconer at maineline dot net

--
Posted via a free Usenet account from http://www.teranews.com

May 14 '07 #17

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

7
by: Nafai | last post by:
Hi. Have a look at this program: struct tmp { short a; int b; short c; }; int main() {
0
by: Lata Neti | last post by:
I am trying to retrieve images from SQL server and display them on the client’s browser. Images in the SQL server are imported from MS Access 2002 I found the following code that mentions about...
4
by: dale zhang | last post by:
Hi, I am trying to save and read an image from MS Access DB based on the following article: http://www.vbdotnetheaven.com/Code/Sept2003/2175.asp Right now, I saved images without any...
5
by: leen | last post by:
hi...i got a problem..i need a help..when i hv load 38000 image files in database ..i need to sort the file refer to the name of the file..like a103.bmp,a104.bmp,a105.bmp..bc­oz when i sort it..it...
2
by: Cameron Walsh | last post by:
Hi all, I'm trying to extract the data from a bitmap or .pnm file using the following code: import Image img = Image.open("test.bmp","r") data=img.getdata() Unfortunately I get the...
0
by: kartic03 | last post by:
<Root> <Family ID="1"> <Member Name="Abe" DOB="3/31/42" /> <Member Name="Betty" DOB="2/4/49" /> <Member Name="Cathy" DOB="12/2/78" /> <Member Name="Dan" Father="Abe"...
3
by: Harry | last post by:
#include<stdio.h> #include<stdlib.h> #include<malloc.h> void scramble(void); struct bmp_header { short int sig; int size_bmp;
3
by: =?iso-8859-9?B?RGlu52F5IEFr5/ZyZW4=?= | last post by:
When I execute the following code #include <stdio.h> #include <stdlib.h> int main(void) { FILE *bmp; bmp = fopen("deneme.bmp","w"); fputc(10,bmp);
6
by: anjanaanupindi | last post by:
I have the following problem: My program is supposed to read data from files to an array. The files are numbered: capture.bmp,capture.bmp and so on. And I really don't want to do the same step for so...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.