Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

Accessing .BMP files -- Can anyone help? (URGENT)

Posted on 1999-07-24
14
Medium Priority
?
336 Views
Last Modified: 2010-05-18
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;
}
0
Comment
Question by:nglp
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 6
  • 4
  • 2
  • +2
14 Comments
 
LVL 1

Expert Comment

by:shivers
ID: 1263839
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...
0
 
LVL 4

Expert Comment

by:wylliker
ID: 1263840
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).

0
 
LVL 4

Expert Comment

by:wylliker
ID: 1263841
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).

0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 

Author Comment

by:nglp
ID: 1263842

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!!
0
 

Author Comment

by:nglp
ID: 1263843

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!!
0
 

Accepted Solution

by:
yoni_o earned 40 total points
ID: 1263844
well, before you can manipulate individual pixels,
first you have to know the bitmap file has an structure. it consists of a header,a body-pallete and a body-pixels.
the header is like this:

struct bmpinf
{
  int id;
  unsigned long tam; //size of body
  unsigned char fil1[4];
  word desp;         //where the bmp-body starts
  unsigned char fil2[2];
  word desppal;     // where the color-pallete starts
  unsigned char fil3[2];
  word x,xi,y,yi;   //coordinates of bmp
  word pal,numcolors;  
  unsigned char fil4[2];
} bi;

then you can read the bmp-header with :
// .......
  unsigned char *ptrbmp;
  unsigned int xa;

///...
  FILE  *filebmp;

   if((filebmp=fopen(name,"rb"))==NULL){
         printf("I can't open %s.\n",name);
       return 1;
    }  
  fseek(filebmp,0L,SEEK_SET);
  fread(&bi,sizeof(struct bmpinf),1,filebmp);
  bi.tam-=bi.desp;
  xa=(word)(bi.tam/bi.y);
  xa<<=1;
  ptrbmp=(unsigned char *)malloc(bi.tam);
  if (ptrbmp) {
     flag=1;
     fseek(filebmp,bi.desp,SEEK_SET);
     fread(ptrbmp,bi.tam,1,filebmp);
  }
  else flag=0; //error
}
//.........
Next ptrbmp will have the body of the bitmap
In this moment you can show the bitmap.

///int i,j,p
  i=0,j=bi.y-1,p;
  if (!flag) fseek(filebmp,bi.desp,SEEK_SET);
  while(1)
  {
        if (flag) p=*ptrbmp++;
        else p=fgetc(filebmp);

        if((i<bi.x)&&(bi.x<=xa)) putpixel(i,j,p>>4);
//nglp: in the previous sentence you can introduce a //condition:
//if p>>4 != COLOR_YOU_WISH  ;//(hexadecimal way)
//else  putpixel(i,j,p>>4)

        if(++i==xa) { i=0;
                      if(--j==-1) break;
                    }

        if((i<bi.x)&&(bi.x<=xa)) putpixel(i,j,p&15);
//nglp: the same thing
//if p&15 != COLOR_YOU_WISH  ;
//else  putpixel(i,j,p>>4)

        if(++i==xa) { i=0;
                      if(--j==-1) break;
                    }
 }




I'll wait your comments.

0
 

Author Comment

by:nglp
ID: 1263845
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??
0
 

Expert Comment

by:yoni_o
ID: 1263846
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);
}

0
 

Author Comment

by:nglp
ID: 1263847
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.
0
 

Expert Comment

by:yoni_o
ID: 1263848
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.

0
 

Expert Comment

by:yoni_o
ID: 1263849
give me a little time.
0
 

Author Comment

by:nglp
ID: 1263850

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

Author Comment

by:nglp
ID: 1263851
hello... u still there??
0
 
LVL 1

Expert Comment

by:Moondancer
ID: 6820326
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
0

Featured Post

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Summary: This tutorial covers some basics of pointer, pointer arithmetic and function pointer. What is a pointer: A pointer is a variable which holds an address. This address might be address of another variable/address of devices/address of fu…
This is a short and sweet, but (hopefully) to the point article. There seems to be some fundamental misunderstanding about the function prototype for the "main" function in C and C++, more specifically what type this function should return. I see so…
The goal of this video is to provide viewers with basic examples to understand how to use strings and some functions related to them in the C programming language.
Video by: Grant
The goal of this video is to provide viewers with basic examples to understand and use nested-loops in the C programming language.

705 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question