You are here:

C/read BMP

Advertisement


Question
QUESTION: Hi,

I found this C code on the internet. They claim that it works (reads bmp files) but when I run it, the compiler says that the first declaration contains syntax error. I'd very much appreciate if you could suggest what might be wrong with the first declaration and why the program won't compile. Also, I don't know where to put the filename that the program is supposed to work on.
Thanks a lot!
Eric

#include <stdio.h>
#include <stdlib.h>
#include <dos.h>
#include <mem.h>
#include <errno.h>


unsigned char* read_windows_bmp(const char* infilename, ImageHeader* header)
{
FILE*infile = NULL;/* input file handle */
unsigned char*image_ptr = NULL;/* pointer to output image in memory */
unsigned char*writep = NULL;/* temp pointer writing to image */
BMPHeaderbh;/* BMP header */
charmode[] = "rb";/* mode to write to file */
unsigned longrow;/* row iterator */
unsigned longcol;/* column iterator */


/* Open the BMP File */
if ( (infile = fopen(infilename, mode)) == NULL )
{
fprintf(stderr, "can't open %s\n", infilename);
return image_ptr;
}

/* read first two bytes */
fread(&bh.magic1, sizeof(unsigned char), 1, infile);
fread(&bh.magic2, sizeof(unsigned char), 1, infile);

/* test to see if this is really a BMP file */
if (bh.magic1 != 'B' && bh.magic2 != 'M')
return image_ptr;

/* read header information */
pm_read_little_long(infile, (long*)&bh.filesize);
pm_read_little_short(infile, (short*)&bh.res1);
pm_read_little_short(infile, (short*)&bh.res2);
pm_read_little_long(infile, (long*)&bh.pixeloffset);
pm_read_little_long(infile, (long*)&bh.bmisize);
pm_read_little_long(infile, (long*)&bh.cols);
pm_read_little_long(infile, (long*)&bh.rows);
pm_read_little_short(infile, (short*)&bh.planes);
pm_read_little_short(infile, (short*)&bh.bitsperpixel);
pm_read_little_long(infile, (long*)&bh.compression);
pm_read_little_long(infile, (long*)&bh.cmpsize);
pm_read_little_long(infile, (long*)&bh.xscale);
pm_read_little_long(infile, (long*)&bh.yscale);
pm_read_little_long(infile, (long*)&bh.colors);
pm_read_little_long(infile, (long*)&bh.impcolors);

/* If compressed, bail */
if ( bh.compression )
{
fprintf(stderr, "%s is compressed.\n", infilename);
return image_ptr;
}

/* set out header information */
header -> width = bh.cols;
header -> length = bh.rows;
header -> spp = (bh.bitsperpixel == 24) ? 3 : 1;
header -> rowbytes = header -> width * header -> spp;
header -> colorspace = (bh.bitsperpixel == 24) ? RGB_24_BIT : INDEX_8_BIT;

if ( header -> colorspace == INDEX_8_BIT )
;/* need to read color table */

/* move to start of image data */
rewind(infile);
fseek(infile, (long)bh.pixeloffset, SEEK_SET);

/* allocate space for new image */
image_ptr = init_image(*header, 0);

/* Windows BMP files are backwards so move write pointer to end of image */
writep = image_ptr + ( header -> rowbytes * header -> length );

/* only read 24 bit images for now */
if ( header -> colorspace == RGB_24_BIT )
{
/* loop through the image data */
for ( row = 0; row < header -> length; row++ )
{
/* backup one row */
writep -= header -> rowbytes;

for ( col = 0; col < header -> width; col++ )
{
/* read blue byte */
fread((writep+2), sizeof(unsigned char), 1, infile);
/* read green byte */
fread((writep+1), sizeof(unsigned char), 1, infile);
/* read red byte */
fread((writep+0), sizeof(unsigned char), 1, infile);
/* advance three bytes */
writep += 3;
}
/* backup another row */
writep -= header -> rowbytes;
}
}
else
fprintf(stderr, "%s is an indexed image.\n", infilename);

/* close file */
fclose(infile);

return image_ptr;
}
Knock yourself out (not all structure include in the code below):

unsigned char* read_windows_bmp(const char* infilename, ImageHeader* header)
{
FILE*infile = NULL;/* input file handle */
unsigned char*image_ptr = NULL;/* pointer to output image in memory */
unsigned char*writep = NULL;/* temp pointer writing to image */
BMPHeaderbh;/* BMP header */
charmode[] = "rb";/* mode to write to file */
unsigned longrow;/* row iterator */
unsigned longcol;/* column iterator */

/* Open the BMP File */
if ( (infile = fopen(infilename, mode)) == NULL )
{
fprintf(stderr, "can't open %s\n", infilename);
return image_ptr;
}

/* read first two bytes */
fread(&bh.magic1, sizeof(unsigned char), 1, infile);
fread(&bh.magic2, sizeof(unsigned char), 1, infile);

/* test to see if this is really a BMP file */
if (bh.magic1 != 'B' && bh.magic2 != 'M')
return image_ptr;

/* read header information */
pm_read_little_long(infile, (long*)&bh.filesize);
pm_read_little_short(infile, (short*)&bh.res1);
pm_read_little_short(infile, (short*)&bh.res2);
pm_read_little_long(infile, (long*)&bh.pixeloffset);
pm_read_little_long(infile, (long*)&bh.bmisize);
pm_read_little_long(infile, (long*)&bh.cols);
pm_read_little_long(infile, (long*)&bh.rows);
pm_read_little_short(infile, (short*)&bh.planes);
pm_read_little_short(infile, (short*)&bh.bitsperpixel);
pm_read_little_long(infile, (long*)&bh.compression);
pm_read_little_long(infile, (long*)&bh.cmpsize);
pm_read_little_long(infile, (long*)&bh.xscale);
pm_read_little_long(infile, (long*)&bh.yscale);
pm_read_little_long(infile, (long*)&bh.colors);
pm_read_little_long(infile, (long*)&bh.impcolors);

/* If compressed, bail */
if ( bh.compression )
{
fprintf(stderr, "%s is compressed.\n", infilename);
return image_ptr;
}

/* set out header information */
header -> width = bh.cols;
header -> length = bh.rows;
header -> spp = (bh.bitsperpixel == 24) ? 3 : 1;
header -> rowbytes = header -> width * header -> spp;
header -> colorspace = (bh.bitsperpixel == 24) ? RGB_24_BIT : INDEX_8_BIT;

if ( header -> colorspace == INDEX_8_BIT )
;/* need to read color table */

/* move to start of image data */
rewind(infile);
fseek(infile, (long)bh.pixeloffset, SEEK_SET);

/* allocate space for new image */
image_ptr = init_image(*header, 0);

/* Windows BMP files are backwards so move write pointer to end of image */
writep = image_ptr + ( header -> rowbytes * header -> length );

/* only read 24 bit images for now */
if ( header -> colorspace == RGB_24_BIT )
{
/* loop through the image data */
for ( row = 0; row < header -> length; row++ )
{
/* backup one row */
writep -= header -> rowbytes;

for ( col = 0; col < header -> width; col++ )
{
/* read blue byte */
fread((writep+2), sizeof(unsigned char), 1, infile);
/* read green byte */
fread((writep+1), sizeof(unsigned char), 1, infile);
/* read red byte */
fread((writep+0), sizeof(unsigned char), 1, infile);
/* advance three bytes */
writep += 3;
}
/* backup another row */
writep -= header -> rowbytes;
}
}
else
fprintf(stderr, "%s is an indexed image.\n", infilename);

/* close file */
fclose(infile);

return image_ptr;
}
ANSWER: It will be easier to analyze, if you post the exact errors that you are seeing.
But, I don't see any error with the first statement of this code.
The only reason it could be throwing error is, it is missing main() function.
Try to add a main() function and then try to compile.

---------- FOLLOW-UP ----------

QUESTION:  Hi,

Thank you very much for your help. However, adding main() function did not make this code work. The error message I'm getting is that line 8 has a "declaration syntax error". Please see the code above. Did it compile on your compiler? Where do you specify the filename? I use Torbo C. Thanks. Eric.  

Answer
I don't see any error in the first line.
The problem could be due to some "Non-Printable characters" which are not seen by human eye.
It could have happened due to the editor you are using or if you have transferred the code between windows and unix.
So, in your editor enable viewing of "Non-Printable characters" and then see if any extraneous bits have been introduced.

But, I can see problem at line# 8:
unsigned char* read_windows_bmp(const char* infilename, ImageHeader* header)
Where is the definition for "ImageHeader"?
Check the place where you downloaded the code from. They must have mentioned some necessary libraries.
I don't think we have something called "ImageHeader" in ANSI C.

-Narendra

C

All Answers


Answers by Expert:


Ask Experts

Volunteer


Narendra

Expertise

I can answer questions in C related to programming, data structures, pointers and file manipulation. I use Solaris for doing C code and if you have questions related to C programming on Solaris, I will be able to help better.

Experience

6.5

Organizations belong to
Sun Microsystems

Awards and Honors
Brain Bench Certified Expert C programmer.
Advanced System Software Certified

©2012 About.com, a part of The New York Times Company. All rights reserved.