I did a bit of testing and extended Patrice's program a bit. I'm not a good C programmer, so all credit goes to him and my parts aren't as elegant as his - sorry for that.
Warning: huge source code ahead.
#include <stdio.h>
#pragma pack(2)
typedef struct
{
char signature[2];
unsigned int fileSize;
unsigned int reserved;
unsigned int offset;
} BmpHeader;
typedef struct
{
unsigned int headerSize;
unsigned int width;
unsigned int height;
unsigned short planeCount;
unsigned short bitDepth;
unsigned int compression;
unsigned int compressedImageSize;
unsigned int horizontalResolution;
unsigned int verticalResolution;
unsigned int numColors;
unsigned int importantColors;
} BmpImageInfo;
typedef struct
{
unsigned char blue;
unsigned char green;
unsigned char red;
//unsigned char reserved; Removed for convenience in fread; info.bitDepth/8 doesn't seem to work for some reason
} Rgb;
int main( int argc, char **argv ) {
FILE *inFile;
BmpHeader header;
BmpImageInfo info;
Rgb *palette;
int i = 0;
printf( "Opening file %s for reading.\n", argv[1] );
inFile = fopen( argv[1], "rb" );
if( !inFile ) {
printf( "Error opening file %s.\n", argv[1] );
return -1;
}
if( fread(&header, 1, sizeof(BmpHeader), inFile) != sizeof(BmpHeader) ) {
printf( "Error reading bmp header.\n" );
return -1;
}
if( fread(&info, 1, sizeof(BmpImageInfo), inFile) != sizeof(BmpImageInfo) ) {
printf( "Error reading image info.\n" );
return -1;
}
if( info.numColors > 0 ) {
printf( "Reading palette.\n" );
palette = (Rgb*)malloc(sizeof(Rgb) * info.numColors);
if( fread(palette, sizeof(Rgb), info.numColors, inFile) != (info.numColors * sizeof(Rgb)) ) {
printf( "Error reading palette.\n" );
return -1; // error
}
}
printf( "Opening file %s for writing.\n", argv[2] );
FILE *outFile = fopen( argv[2], "wb" );
if( !outFile ) {
printf( "Error opening outputfile.\n" );
return -1;
}
Rgb *pixel = (Rgb*) malloc( sizeof(Rgb) );
int read, j;
for( j=0; j<info.height; j++ ) {
printf( "------ Row %d\n", j+1 );
read = 0;
for( i=0; i<info.width; i++ ) {
if( fread(pixel, 1, sizeof(Rgb), inFile) != sizeof(Rgb) ) {
printf( "Error reading pixel!\n" );
return -1;
}
read += sizeof(Rgb);
printf( "Pixel %d: %3d %3d %3d\n", i+1, pixel->red, pixel->green, pixel->blue );
}
if( read % 4 != 0 ) {
read = 4 - (read%4);
printf( "Padding: %d bytes\n", read );
fread( pixel, read, 1, inFile );
}
}
printf( "Done.\n" );
fclose(inFile);
fclose(outFile);
printf( "\nBMP-Info:\n" );
printf( "Width x Height: %i x %i\n", info.width, info.height );
printf( "Depth: %i\n", (int)info.bitDepth );
return 0;
}
This program reads out the pixel information stored in the file. It takes the padding into account but only works with bmps with a 24 bits per pixel color depth (If you need other depths, you'll have to customize the Rgb struct). Hope this helps you, but as I said, it's just an extension of Patrice's code.
Here's a sample output from my testfile:
$ ./a.out test.bmp out.txt
Opening file test.bmp for reading.
Opening file out.txt for writing.
------ Row 1
Pixel 1: 0 0 0
Pixel 2: 0 0 0
Pixel 3: 0 0 0
Pixel 4: 0 0 0
Pixel 5: 0 0 0
Padding: 1 bytes
------ Row 2
Pixel 1: 0 0 0
Pixel 2: 232 33 33
Pixel 3: 0 0 0
Pixel 4: 232 33 33
Pixel 5: 0 0 0
Padding: 1 bytes
------ Row 3
Pixel 1: 0 0 0
Pixel 2: 0 0 0
Pixel 3: 232 33 33
Pixel 4: 0 0 0
Pixel 5: 0 0 0
Padding: 1 bytes
------ Row 4
Pixel 1: 0 0 0
Pixel 2: 232 33 33
Pixel 3: 0 0 0
Pixel 4: 232 33 33
Pixel 5: 0 0 0
Padding: 1 bytes
------ Row 5
Pixel 1: 0 0 0
Pixel 2: 0 0 0
Pixel 3: 0 0 0
Pixel 4: 0 0 0
Pixel 5: 0 0 0
Padding: 1 bytes
Done.
BMP-Info:
Width x Height: 5 x 5
Depth: 24
Edit: Yes, my image is displaying a red cross. Note that the image is stored upside-down so row 1 of the file is actually row 5 of the image. D'oh forgot to write something to file the code opens, but this is left as an excercise up to you ;).