Link to home
Start Free TrialLog in
Avatar of nglp
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;
}
Avatar of shivers
shivers

ok, firstly you want to open the file in binary mode - by usinf "rb" instead of "r" in the fopen() call, then you must use different I/O calls to read the data - fscanf is for reading ASCII data only

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...
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).

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).

Avatar of nglp

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!!
Avatar of nglp

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
Avatar of yoni_o
yoni_o

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of nglp

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??
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,tRGB);
}

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,&outregs);
}

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);
}

Avatar of nglp

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.
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.

give me a little time.
Avatar of nglp

ASKER


do u want me to attach the code for reading of file so that ??
Avatar of nglp

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