nglp
asked on
Accessing .BMP files -- Can anyone help? (URGENT)
I want to access the individual pixels in .bmp files. First, I wrote the short program below to read in the file. But it seems to only read in ascii value, not in hexadecimal form. What shd I do? Thanks alot!!!
#include <stdio.h>
main ()
{
char value1[3];
char value2[3];
FILE *cfPtr;
if ((cfPtr=fopen("empty.bmp", "r"))==NULL)
printf("File cannot be opened\n");
else
{
printf("Opening file...\n");
fscanf(cfPtr, "%s%s", value1, value2);
printf("%-10s%-13s\n", value1, value2);
fscanf(cfPtr, "%s%s", value1, value2);
fclose(cfPtr);
}
return 0;
}
#include <stdio.h>
main ()
{
char value1[3];
char value2[3];
FILE *cfPtr;
if ((cfPtr=fopen("empty.bmp",
printf("File cannot be opened\n");
else
{
printf("Opening file...\n");
fscanf(cfPtr, "%s%s", value1, value2);
printf("%-10s%-13s\n", value1, value2);
fscanf(cfPtr, "%s%s", value1, value2);
fclose(cfPtr);
}
return 0;
}
Though you didn't say what you will be doing with the bitmap data, keep the following in mind with binary data ...
Another thing be careful about is that if you dynamically allocate memory as a buffer for the fread() call or if you create just an array that you declare it as - unsigned char, otherwise you might run into trouble if you manipulate the data in the bitmap as C compilers promote char to int behind the scenes in expressions and the sign bit might cause you trouble.
This would be the case if you were to do any bit shifting for example:
char Buffer[1000];
char c;
... somewhere in a loop you are doing some bit manipulation
c = Buffer[N];
c >>= 2;
If the value of c were to be greater than 127 (for a char a negative value) you will not get your expected results.
So if the value in Buffer[N] was: 10010110 binary
With a signed (default) char you have
-106 decimal - 96 hex - 10010110 binary
^ - Sign bit
You would expect a right shift of 2 to produce:
37 decimal - 25 hex - 00100101 binary
^- Sign bit
When in fact it will produce (the sign will not change!):
245 decimal - E5 hex - 11100101
^- Sign bit
If you had declared c and Buffer as unsigned char you would have gotten the desired:
37 decimal - 25 hex - 00100101 binary
NOTE that as long as all values of Buffer[N] were < 128 (for a char), the code would work fine as it is only a problem when a value is negative (> 127 for a char).
Another thing be careful about is that if you dynamically allocate memory as a buffer for the fread() call or if you create just an array that you declare it as - unsigned char, otherwise you might run into trouble if you manipulate the data in the bitmap as C compilers promote char to int behind the scenes in expressions and the sign bit might cause you trouble.
This would be the case if you were to do any bit shifting for example:
char Buffer[1000];
char c;
... somewhere in a loop you are doing some bit manipulation
c = Buffer[N];
c >>= 2;
If the value of c were to be greater than 127 (for a char a negative value) you will not get your expected results.
So if the value in Buffer[N] was: 10010110 binary
With a signed (default) char you have
-106 decimal - 96 hex - 10010110 binary
^ - Sign bit
You would expect a right shift of 2 to produce:
37 decimal - 25 hex - 00100101 binary
^- Sign bit
When in fact it will produce (the sign will not change!):
245 decimal - E5 hex - 11100101
^- Sign bit
If you had declared c and Buffer as unsigned char you would have gotten the desired:
37 decimal - 25 hex - 00100101 binary
NOTE that as long as all values of Buffer[N] were < 128 (for a char), the code would work fine as it is only a problem when a value is negative (> 127 for a char).
Though you didn't say what you will be doing with the bitmap data, keep the following in mind with binary data ...
Another thing be careful about is that if you dynamically allocate memory as a buffer for the fread() call or if you create just an array that you declare it as - unsigned char, otherwise you might run into trouble if you manipulate the data in the bitmap as C compilers promote char to int behind the scenes in expressions and the sign bit might cause you trouble.
This would be the case if you were to do any bit shifting for example:
char Buffer[1000];
char c;
... somewhere in a loop you are doing some bit manipulation
c = Buffer[N];
c >>= 2;
If the value of c were to be greater than 127 (for a char a negative value) you will not get your expected results.
So if the value in Buffer[N] was: 10010110 binary
With a signed (default) char you have
-106 decimal - 96 hex - 10010110 binary
^ - Sign bit
You would expect a right shift of 2 to produce:
37 decimal - 25 hex - 00100101 binary
^- Sign bit
When in fact it will produce (the sign will not change!):
245 decimal - E5 hex - 11100101
^- Sign bit
If you had declared c and Buffer as unsigned char you would have gotten the desired:
37 decimal - 25 hex - 00100101 binary
NOTE that as long as all values of Buffer[N] were < 128 (for a char), the code would work fine as it is only a problem when a value is negative (> 127 for a char).
Another thing be careful about is that if you dynamically allocate memory as a buffer for the fread() call or if you create just an array that you declare it as - unsigned char, otherwise you might run into trouble if you manipulate the data in the bitmap as C compilers promote char to int behind the scenes in expressions and the sign bit might cause you trouble.
This would be the case if you were to do any bit shifting for example:
char Buffer[1000];
char c;
... somewhere in a loop you are doing some bit manipulation
c = Buffer[N];
c >>= 2;
If the value of c were to be greater than 127 (for a char a negative value) you will not get your expected results.
So if the value in Buffer[N] was: 10010110 binary
With a signed (default) char you have
-106 decimal - 96 hex - 10010110 binary
^ - Sign bit
You would expect a right shift of 2 to produce:
37 decimal - 25 hex - 00100101 binary
^- Sign bit
When in fact it will produce (the sign will not change!):
245 decimal - E5 hex - 11100101
^- Sign bit
If you had declared c and Buffer as unsigned char you would have gotten the desired:
37 decimal - 25 hex - 00100101 binary
NOTE that as long as all values of Buffer[N] were < 128 (for a char), the code would work fine as it is only a problem when a value is negative (> 127 for a char).
ASKER
Right now, what I want to do is to manipulate the pixels, say for example, take the lower half portion of the bitmap picture and put it on top instead.
Which format (binary or hexadecimal?) should I work with in this case? I must be able to recognize the RGB colours as the .bmp file is from a scanned photograph.
My ultimate aim is actually to recognize the individual pixels according to it's colour in RGB format, and then reproduce ONLY the pixels with a particular colour combination (at their original positions) and display this new image file.
Thanks!!
ASKER
Right now, what I want to do is to manipulate the pixels, say for example, take the lower half portion of the bitmap picture and put it on top instead.
Which format (binary or hexadecimal?) should I work with in this case? I must be able to recognize the RGB colours as the .bmp file is from a scanned photograph.
My ultimate aim is actually to recognize the individual pixels according to it's colour in RGB format, and then reproduce ONLY the pixels with a particular colour combination (at their original positions) and display this new image file.
Thanks!!
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
thanks for providing an answer :)
say i can now read in the bitmap file (by storing the body of pixels into 2 dimensional array), can u explain further the code for showing of the new image file?? i'm still quite blur abt it..
do u mean i must fopen another file for writing only, and does the 'putpixels' refer to the fwrite command?? in this case, if fwrite only writes to the new file, that means the code doesn't include displaying the new file. am i rite?
also, is the palette info of the bitmap useful?? if so, why doesn't the code include it??
say i can now read in the bitmap file (by storing the body of pixels into 2 dimensional array), can u explain further the code for showing of the new image file?? i'm still quite blur abt it..
do u mean i must fopen another file for writing only, and does the 'putpixels' refer to the fwrite command?? in this case, if fwrite only writes to the new file, that means the code doesn't include displaying the new file. am i rite?
also, is the palette info of the bitmap useful?? if so, why doesn't the code include it??
do you want i explain the code for showing the bmp?
Yes, you can fopen another file for wrting only, and you also can show the new bitmap, while you are writting.
The pallete is useful, you can use next procs.
//VIDEO = 0x10
//struct RGB
//{
// unsigned char rojo;
// unsigned char verde;
// unsigned char azul;
//};
void setpalbmp(){
unsigned char buff[64],rgb[48],idreg[17] ;
struct RGB tRGB[16];
register i,j=0;
fseek(filebmp,54L,SEEK_SET );
fread(buff,64,1,filebmp);
for(i=0;i<64;i++)
if((i+1)%4) rgb[j++]=(char)(buff[i]>>2 );
memcpy(&tRGB,&rgb,48);
cambia_pal_actual(idreg,tR GB);
}
void cambia_pal_actual(unsigned char idreg[],struct RGB tabla[])
{
int x;
get_paleta(idreg);
for(x=0;x<16;x++) set_rgb(idreg[x],tabla[x]) ;
}
void set_rgb(int regdac,struct RGB tabla)
{
union REGS inregs,outregs;
inregs.h.al=0x10;
inregs.h.ah=PALETA;
inregs.h.dh=tabla.rojo;
inregs.h.ch=tabla.verde;
inregs.h.dl=tabla.azul;
inregs.h.bl=regdac;
int86(VIDEO,&inregs,&outre gs);
}
void get_paleta(unsigned char buf[])
{
struct REGPACK inr;
inr.r_ax=0x1009;
inr.r_es=FP_SEG(buf);
inr.r_dx=FP_OFF(buf);
intr(VIDEO,&inr);
}
Yes, you can fopen another file for wrting only, and you also can show the new bitmap, while you are writting.
The pallete is useful, you can use next procs.
//VIDEO = 0x10
//struct RGB
//{
// unsigned char rojo;
// unsigned char verde;
// unsigned char azul;
//};
void setpalbmp(){
unsigned char buff[64],rgb[48],idreg[17]
struct RGB tRGB[16];
register i,j=0;
fseek(filebmp,54L,SEEK_SET
fread(buff,64,1,filebmp);
for(i=0;i<64;i++)
if((i+1)%4) rgb[j++]=(char)(buff[i]>>2
memcpy(&tRGB,&rgb,48);
cambia_pal_actual(idreg,tR
}
void cambia_pal_actual(unsigned
{
int x;
get_paleta(idreg);
for(x=0;x<16;x++) set_rgb(idreg[x],tabla[x])
}
void set_rgb(int regdac,struct RGB tabla)
{
union REGS inregs,outregs;
inregs.h.al=0x10;
inregs.h.ah=PALETA;
inregs.h.dh=tabla.rojo;
inregs.h.ch=tabla.verde;
inregs.h.dl=tabla.azul;
inregs.h.bl=regdac;
int86(VIDEO,&inregs,&outre
}
void get_paleta(unsigned char buf[])
{
struct REGPACK inr;
inr.r_ax=0x1009;
inr.r_es=FP_SEG(buf);
inr.r_dx=FP_OFF(buf);
intr(VIDEO,&inr);
}
ASKER
1. yes, please explain the code for showing bmp.
2. can u also give code to explain how u show the bitmap while writing.
3. i dun understand what u mean by 'use next procs' for the palette.
2. can u also give code to explain how u show the bitmap while writing.
3. i dun understand what u mean by 'use next procs' for the palette.
1. and 2. I'll prepare the program and next i'll explain you.
3. Well, i mean you can use those functions for show the pallette.
3. Well, i mean you can use those functions for show the pallette.
give me a little time.
ASKER
do u want me to attach the code for reading of file so that ??
ASKER
hello... u still there??
This question was awarded, but never cleared due to the JSP-500 errors of that time. It was "stuck" against userID -1 versus the intended expert whom you awarded. This corrects that and the expert will now receive these points, all verified.
Moondancer
Moderator @ Experts Exchange
Moondancer
Moderator @ Experts Exchange
fread() is probably the best one - to read a chunk of the file directly to a memory address
Have you got info on the file format spec for BMP files? if not - I will post it for you...