![]() |
| | #1 |
| Registered User Join Date: Dec 2004 Location: Brazil, Porto Alegre
Posts: 152
| Problem reading BMP Here is the code of bitmap.h: Code: #include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#define BMP_TYPE 19778
typedef struct{
unsigned short type; /* Magic identifier */
unsigned int size; /* File size in bytes */
unsigned short int reserved1, reserved2;
unsigned int offset; /* Offset to image data, bytes */
unsigned int hsize; /* Header size in bytes */
int width,height; /* Width and height of image */
unsigned short int planes; /* Number of colour planes */
unsigned short int bits; /* Bits per pixel */
unsigned int compression; /* Compression type */
unsigned int imagesize; /* Image size in bytes */
int xresolution,yresolution; /* Pixels per meter */
unsigned int ncolours; /* Number of colours */
unsigned int importantcolours; /* Important colours */
} HEADER;
typedef struct{
HEADER header;
char* data;
} BMP;
void loadFile( char* fileName, BMP** bmp );
void writeFile( char* fileName, BMP* bmp );
Code: #include "bitmap.h"
void loadFile( char* filenName, BMP** pbmp ){
struct stat stat_file;
FILE* file;
BMP* bmp;
// recover file statistics
stat( filenName, &stat_file );
*pbmp = (BMP*) malloc( stat_file.st_size );
if( !(*pbmp) ){
fprintf(stderr, "It was not possible to allocate some memory.\n");
exit(1);
}
// to ease manipulation
bmp = *pbmp;
// open bitmap file
file = fopen( filenName, "r" );
// read all the file into pbmp structure
fread( bmp, 1, stat_file.st_size, file );
// we must convert from little-endian to big-endian
// the error is here, inspection of the file
// shows that size is non zero
// printf("File size is %d\n", ntohl(bmp->header.size) );
printf("File size is %d\n", (((char*)bmp)[2]));
}
void writeFile( char* filenName, BMP* bmp ){
struct stat stat_file;
int file = open( filenName, O_RDWR );
if( write( file, bmp, stat_file.st_size ) < stat_file.st_size ){
perror( "Error saving file.\n" );
exit(1);
}
}
|
| Mortissus is offline | |
| | #2 |
| Registered User Join Date: Aug 2001 Location: Newport, South Wales, UK
Posts: 1,094
| Mam-ma mi-a! You-a crazziee keeed! ![]() First, look at this page, where Microsoft has kindly illustrated the structure of a BMP file. Note in particular the presence of an unspecified number of RGBQUAD structures. This is where palette information is stored, and thus where your code's gonna fall over in all sorts of personally amusing ways when you actually get round to testing this thing. Unfortunately you can't just pack x RGBQUADs into the massive struct you've defined, so you're gonna have to do yourself a favour and stick a little bit closer to the way MS do it, i.e. Code: typedef struct{
HEADER header;
RGBQUAD *palette;
char* data;
} BMP;
Code: *pbmp = (BMP*) malloc( stat_file.st_size ); ![]() Code: file = fopen( filenName, "r" ); As for your so-called endian problem, your bizarre little cast at the end of that printf statement there serves no one and nothing. Also ntohl converts from network byte order (which if you read the spec is big endian) to host byte order, which for you would appear to be... you guessed it, big endian!. If you really want to change the byte order, try this cheap little function for size:- Code: void SwapDword(unsigned long *ulIn)
{
unsigned char *ucIn, ucTemp;
ucIn = (unsigned char *)ulIn;
ucTemp = *ucIn;
*ucIn = *(ucIn + 3);
*(ucIn + 3) = ucTemp;
ucTemp = *(ucIn + 1);
*(ucIn + 1) = *(ucIn + 2);
*(ucIn + 2) = ucTemp;
}
|
| SMurf is offline | |
| | #3 |
| Registered User Join Date: Dec 2004 Location: Brazil, Porto Alegre
Posts: 152
| First, thanks for all answers. Two answers does not appear here, but I have read them in my e-mail. Second, I have changed the open statment to open the file as binary. Also, I have removed the ntohl (i swear it worked). I didnt added the RGBQUAD structure yet, SMurf, since my problem is before I reach this point. I am sorry SMurf, but I dont speak german, what is wrong with my malloc? Just in case you were speaking about the *pbmp, it is because the functions receives a BMP**. Sorry my bad english. After all these modifications I still have the same problem, the size (second field of header) is zero. Thanks again. |
| Mortissus is offline | |
| | #4 |
| old man Join Date: Dec 2005
Posts: 90
| I also don't think that your struct will work very well ... for example, you're inviting padding problems with shorts intermixed in the header. Depending on your compiler, the struct will very possibly lose sync with your data. As for malloc, it makes no sense to cast it to anything, since it only cares about the size argument, and your pointer is already declared -- your pointer is the only tool that matters when it come to accessing the data. Here's an example of getting that bmp size field. It solves your problem with endianness (which was likely your main problem all along). Code: #include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
void
die (char *s)
{
perror (s);
printf ("\n");
exit (EXIT_FAILURE);
}
unsigned int
get_dw (char *b)
{
return ((((((b[3] << 8)
| b[2]) << 8)
| b[1]) << 8)
| b[0]);
}
void
load_bmp (char *fn)
{
struct stat fs; char *buf; FILE *fp;
if ((stat (fn, &fs)) == -1)
die ("stat");
buf = malloc (fs.st_size);
if (buf == NULL)
die ("malloc");
fp = fopen (fn, "rb");
if (fp == NULL)
die ("fopen");
fread (buf, 1, fs.st_size, fp);
if (buf[0] != 'B' || buf[1] != 'M')
printf ("This seems not to be a bmp file ...\n\n");
else
printf ("bmp size: %u bytes\n\n", get_dw (buf+2));
fclose (fp);
free (buf);
}
int
main (int argc, char **argv)
{
if (argc != 2)
{
printf ("I need a (single) bmp file ...\n\n");
exit (EXIT_FAILURE);
}
load_bmp (argv[1]);
exit (EXIT_SUCCESS);
}
Last edited by eerok; 02-01-2006 at 12:55 AM. |
| eerok is offline | |
| | #5 |
| Registered User Join Date: Dec 2004 Location: Brazil, Porto Alegre
Posts: 152
| It worked! I understand my errors. I was just trying to do the work in a lazy way. Thanks a lot for the help, I will respect more these details (i have work ed with c++ for 4 years, but I never worked with shorts ints and such). |
| Mortissus is offline | |
![]() |
| Thread Tools | |
| Display Modes | |
|
Similar Threads | ||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| problem with reading struct from file generated by hexdump | wollek | C Programming | 22 | 12-23-2008 01:53 PM |
| Problem reading data from file and record it for use in program | timmer | C Programming | 20 | 06-12-2005 11:53 PM |
| Problem with reading strings | goron350 | C++ Programming | 8 | 06-05-2005 12:05 AM |
| a weird problem with my code on writing & reading from file | goldfish | C Programming | 6 | 05-12-2005 03:39 AM |