主题:菜鸟求助 关于BMP读图的编辑
请问我的code到底是哪里出错咯
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
typedef struct
{
unsigned char fileMarker1; /* 'B' */
unsigned char fileMarker2; /* 'M' */
unsigned int bfSize;
unsigned short unused1;
unsigned short unused2;
unsigned int imageDataOffset; /* Offset to the start of image data */
}FILEHEADER;
typedef struct
{
unsigned int biSize;
int width; /* Width of the image */
int height; /* Height of the image */
unsigned short planes;
unsigned short bitPix;
unsigned int biCompression;
unsigned int biSizeImage;
int biXPelsPerMeter;
int biYPelsPerMeter;
unsigned int biClrUsed;
unsigned int biClrImportant;
}INFOHEADER;
typedef struct
{
unsigned char b; /* Blue value */
unsigned char g; /* Green value */
unsigned char r; /* Red value */
}IMAGECOMPONENT;
int ReadFile(FILE *fp, char *buf, int size)
{
int readnum;
if ((readnum = fread(buf, 1, size, fp)) < 0)
return -1;
return readnum;
}
int ReadFileHeader(FILEHEADER *pFileHeader, FILE *fp)
{
char buf[32], *p;
int size = sizeof(unsigned char) + sizeof(unsigned char) + sizeof(unsigned int) +
sizeof(unsigned short) + sizeof(unsigned short) + sizeof(unsigned int);
if (fread(buf, 1, size, fp) < 0 )
return -1;
p = buf;
pFileHeader->fileMarker1 = *p++;
pFileHeader->fileMarker2 = *p++;
strncpy((char *)&pFileHeader->bfSize, p, sizeof(pFileHeader->bfSize));
p += sizeof(pFileHeader->bfSize);
strncpy((char *)&pFileHeader->unused1, p, sizeof(pFileHeader->unused1));
p += sizeof(pFileHeader->unused1);
strncpy((char *)&pFileHeader->unused2, p, sizeof(pFileHeader->unused2));
p += sizeof(pFileHeader->unused2);
strncpy((char *)&pFileHeader->imageDataOffset, p, sizeof(pFileHeader->imageDataOffset));
p += sizeof(pFileHeader->imageDataOffset);
return 0;
}
int ReadInfoHeader(INFOHEADER *pInfoHeader, FILE *fp)
{
char buf[64], *p;
int size = sizeof(unsigned int) + sizeof(int) + sizeof(int) +
sizeof(unsigned short) + sizeof(unsigned short) + sizeof(unsigned int) +
sizeof(unsigned int) + sizeof(int) + sizeof(int) +
sizeof(unsigned int) + sizeof(unsigned int);
if (fread(buf, 1, size, fp) < 0 )
return -1;
p = buf;
strncpy((char *)&pInfoHeader->biSize, p, sizeof(pInfoHeader->biSize));
p += sizeof(pInfoHeader->biSize);
strncpy((char *)&pInfoHeader->width, p, sizeof(pInfoHeader->width));
p += sizeof(pInfoHeader->width);
strncpy((char *)&pInfoHeader->height, p, sizeof(pInfoHeader->height));
p += sizeof(pInfoHeader->height);
strncpy((char *)&pInfoHeader->planes, p, sizeof(pInfoHeader->planes));
p += sizeof(pInfoHeader->planes);
strncpy((char *)&pInfoHeader->bitPix, p, sizeof(pInfoHeader->bitPix));
p += sizeof(pInfoHeader->bitPix);
strncpy((char *)&pInfoHeader->biCompression, p, sizeof(pInfoHeader->biCompression));
p += sizeof(pInfoHeader->biCompression);
strncpy((char *)&pInfoHeader->biSizeImage, p, sizeof(pInfoHeader->biSizeImage));
p += sizeof(pInfoHeader->biSizeImage);
strncpy((char *)&pInfoHeader->biXPelsPerMeter, p, sizeof(pInfoHeader->biXPelsPerMeter));
p += sizeof(pInfoHeader->biXPelsPerMeter);
strncpy((char *)&pInfoHeader->biYPelsPerMeter, p, sizeof(pInfoHeader->biYPelsPerMeter));
p += sizeof(pInfoHeader->biYPelsPerMeter);
strncpy((char *)&pInfoHeader->biClrUsed, p, sizeof(pInfoHeader->biClrUsed));
p += sizeof(pInfoHeader->biClrUsed);
strncpy((char *)&pInfoHeader->biClrImportant, p, sizeof(pInfoHeader->biClrImportant));
p += sizeof(pInfoHeader->biClrImportant);
return 0;
}
int ReadImageData(IMAGECOMPONENT *pImageData, int size, FILE *fp)
{
char buf[8], *p;
if (fread(buf, 1, size, fp) < 0 )
return -1;
p = buf;
pImageData->b = *p++;
if (size > 1)
pImageData->g = *p++;
if (size > 2)
pImageData->r = *p++;
return 0;
}
int IsBmpFile(char *sValue)
{
unsigned short header = *((unsigned short *)sValue);
// check bmp header
if (header != 0x424D && header != 0x4D42)
return -1;
return 0;
}
int IsBigEndian(char *sValue)
{
unsigned short header = *((unsigned short *)sValue);
if (header == 0x424D)
return 1;
return 0;
}
unsigned int ConvertEndianBigToLittle(unsigned int nBigEndian)
{
return ((nBigEndian<<24)&0xff000000 | (nBigEndian<<8)&0x00ff0000 | (nBigEndian>>8)&0x0000ff00 | (nBigEndian>>24)&0x000000ff);
}
unsigned char Max(unsigned char uc1, unsigned char uc2)
{
return ((uc1 > uc2) ? uc1 : uc2);
}
unsigned char Min(unsigned char uc1, unsigned char uc2)
{
return ((uc1 < uc2) ? uc1 : uc2);
}
int main(int argc, char **argv)
{
char *filename;
FILE *fp;
FILEHEADER rFileHeader;
INFOHEADER rInfoHeader;
IMAGECOMPONENT *pImageData;
int nIsBigEndian = 0, nIsPadByte = 0;
int nImageDataOffset, nWidth, nHeight, nRealWidth;
unsigned char rMax, rMin, gMax, gMin, bMax, bMin;
unsigned long int i, count;
// Check the number of command parameters
if (argc != 2)
{
printf("Incorrect Number Of Command Line Arguments.\n");
exit(0);
}
filename = argv[1];
if ((fp = fopen(filename, "rb")) == NULL)
{
printf("Can't open %s.\n", filename);
exit(0); // open failed and exit
}
if (ReadFileHeader(&rFileHeader, fp) < 0) // get fileheader
{
printf("Read file error.\n");
fclose(fp);
exit(0);
}
if (IsBmpFile((char *)&rFileHeader) == -1)
{
printf("Incorrect File Format.\n");
fclose(fp);
exit(0);
}
nIsBigEndian = IsBigEndian((char *)&rFileHeader);
if (ReadInfoHeader(&rInfoHeader, fp) < 0) // get infoheader
{
printf("Read file error.\n");
fclose(fp);
exit(0);
}
// get imageDataOffset, width, height
nImageDataOffset = (nIsBigEndian == 0) ? rFileHeader.imageDataOffset : ConvertEndianBigToLittle(rFileHeader.imageDataOffset);
nWidth = (nIsBigEndian == 0) ? rInfoHeader.width : ConvertEndianBigToLittle(rInfoHeader.width);
nHeight = (nIsBigEndian == 0) ? rInfoHeader.height : ConvertEndianBigToLittle(rInfoHeader.height);
nIsPadByte = nWidth * 3 % 4; // get pad bytes
nIsPadByte = (nIsPadByte == 0) ? nIsPadByte : (4 - nIsPadByte);
nRealWidth = (nIsPadByte == 0) ? nWidth : (nWidth+1);
pImageData = (IMAGECOMPONENT *)malloc(nRealWidth*nHeight*sizeof(IMAGECOMPONENT));
if (pImageData == NULL)
{
fclose(fp);
exit(0);
}
memset(pImageData, 0, nRealWidth*nHeight*sizeof(IMAGECOMPONENT));
rMax = gMax = bMax = 0;
rMin = gMin = bMin = 255;
count = 0;
// skip image data
fseek(fp, nImageDataOffset, 0);
for (i = 0; i < nRealWidth*nHeight; i++)
{
if ((count == nWidth) && (nIsPadByte != 0))
{
// read pads data
if (ReadImageData(&pImageData[i], nIsPadByte, fp) < 0)
{
printf("Read file error.\n");
free(pImageData);
fclose(fp);
exit(0);
}
count = 0;
}
else
{
count++;
// read real data
if (ReadImageData(&pImageData[i], 3, fp) < 0)
{
printf("Read file error.\n");
free(pImageData);
fclose(fp);
exit(0);
}
rMax = Max(pImageData[i].r, rMax);
rMin = Min(pImageData[i].r, rMin);
gMax = Max(pImageData[i].g, gMax);
gMin = Min(pImageData[i].g, gMin);
bMax = Max(pImageData[i].b, bMax);
bMin = Min(pImageData[i].b, bMin);
}
}
// show info
printf("Image width : %d picture elements\n", nWidth);
printf("Image height : %d picture elements\n", nHeight);
printf("bMax = %-3d\tbMin = %-3d\n", bMax, bMin);
printf("gMax = %-3d\tgMin = %-3d\n", gMax, gMin);
printf("rMax = %-3d\trMin = %-3d\n", rMax, rMin);
free(pImageData);
fclose(fp);
return 1;
}
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
typedef struct
{
unsigned char fileMarker1; /* 'B' */
unsigned char fileMarker2; /* 'M' */
unsigned int bfSize;
unsigned short unused1;
unsigned short unused2;
unsigned int imageDataOffset; /* Offset to the start of image data */
}FILEHEADER;
typedef struct
{
unsigned int biSize;
int width; /* Width of the image */
int height; /* Height of the image */
unsigned short planes;
unsigned short bitPix;
unsigned int biCompression;
unsigned int biSizeImage;
int biXPelsPerMeter;
int biYPelsPerMeter;
unsigned int biClrUsed;
unsigned int biClrImportant;
}INFOHEADER;
typedef struct
{
unsigned char b; /* Blue value */
unsigned char g; /* Green value */
unsigned char r; /* Red value */
}IMAGECOMPONENT;
int ReadFile(FILE *fp, char *buf, int size)
{
int readnum;
if ((readnum = fread(buf, 1, size, fp)) < 0)
return -1;
return readnum;
}
int ReadFileHeader(FILEHEADER *pFileHeader, FILE *fp)
{
char buf[32], *p;
int size = sizeof(unsigned char) + sizeof(unsigned char) + sizeof(unsigned int) +
sizeof(unsigned short) + sizeof(unsigned short) + sizeof(unsigned int);
if (fread(buf, 1, size, fp) < 0 )
return -1;
p = buf;
pFileHeader->fileMarker1 = *p++;
pFileHeader->fileMarker2 = *p++;
strncpy((char *)&pFileHeader->bfSize, p, sizeof(pFileHeader->bfSize));
p += sizeof(pFileHeader->bfSize);
strncpy((char *)&pFileHeader->unused1, p, sizeof(pFileHeader->unused1));
p += sizeof(pFileHeader->unused1);
strncpy((char *)&pFileHeader->unused2, p, sizeof(pFileHeader->unused2));
p += sizeof(pFileHeader->unused2);
strncpy((char *)&pFileHeader->imageDataOffset, p, sizeof(pFileHeader->imageDataOffset));
p += sizeof(pFileHeader->imageDataOffset);
return 0;
}
int ReadInfoHeader(INFOHEADER *pInfoHeader, FILE *fp)
{
char buf[64], *p;
int size = sizeof(unsigned int) + sizeof(int) + sizeof(int) +
sizeof(unsigned short) + sizeof(unsigned short) + sizeof(unsigned int) +
sizeof(unsigned int) + sizeof(int) + sizeof(int) +
sizeof(unsigned int) + sizeof(unsigned int);
if (fread(buf, 1, size, fp) < 0 )
return -1;
p = buf;
strncpy((char *)&pInfoHeader->biSize, p, sizeof(pInfoHeader->biSize));
p += sizeof(pInfoHeader->biSize);
strncpy((char *)&pInfoHeader->width, p, sizeof(pInfoHeader->width));
p += sizeof(pInfoHeader->width);
strncpy((char *)&pInfoHeader->height, p, sizeof(pInfoHeader->height));
p += sizeof(pInfoHeader->height);
strncpy((char *)&pInfoHeader->planes, p, sizeof(pInfoHeader->planes));
p += sizeof(pInfoHeader->planes);
strncpy((char *)&pInfoHeader->bitPix, p, sizeof(pInfoHeader->bitPix));
p += sizeof(pInfoHeader->bitPix);
strncpy((char *)&pInfoHeader->biCompression, p, sizeof(pInfoHeader->biCompression));
p += sizeof(pInfoHeader->biCompression);
strncpy((char *)&pInfoHeader->biSizeImage, p, sizeof(pInfoHeader->biSizeImage));
p += sizeof(pInfoHeader->biSizeImage);
strncpy((char *)&pInfoHeader->biXPelsPerMeter, p, sizeof(pInfoHeader->biXPelsPerMeter));
p += sizeof(pInfoHeader->biXPelsPerMeter);
strncpy((char *)&pInfoHeader->biYPelsPerMeter, p, sizeof(pInfoHeader->biYPelsPerMeter));
p += sizeof(pInfoHeader->biYPelsPerMeter);
strncpy((char *)&pInfoHeader->biClrUsed, p, sizeof(pInfoHeader->biClrUsed));
p += sizeof(pInfoHeader->biClrUsed);
strncpy((char *)&pInfoHeader->biClrImportant, p, sizeof(pInfoHeader->biClrImportant));
p += sizeof(pInfoHeader->biClrImportant);
return 0;
}
int ReadImageData(IMAGECOMPONENT *pImageData, int size, FILE *fp)
{
char buf[8], *p;
if (fread(buf, 1, size, fp) < 0 )
return -1;
p = buf;
pImageData->b = *p++;
if (size > 1)
pImageData->g = *p++;
if (size > 2)
pImageData->r = *p++;
return 0;
}
int IsBmpFile(char *sValue)
{
unsigned short header = *((unsigned short *)sValue);
// check bmp header
if (header != 0x424D && header != 0x4D42)
return -1;
return 0;
}
int IsBigEndian(char *sValue)
{
unsigned short header = *((unsigned short *)sValue);
if (header == 0x424D)
return 1;
return 0;
}
unsigned int ConvertEndianBigToLittle(unsigned int nBigEndian)
{
return ((nBigEndian<<24)&0xff000000 | (nBigEndian<<8)&0x00ff0000 | (nBigEndian>>8)&0x0000ff00 | (nBigEndian>>24)&0x000000ff);
}
unsigned char Max(unsigned char uc1, unsigned char uc2)
{
return ((uc1 > uc2) ? uc1 : uc2);
}
unsigned char Min(unsigned char uc1, unsigned char uc2)
{
return ((uc1 < uc2) ? uc1 : uc2);
}
int main(int argc, char **argv)
{
char *filename;
FILE *fp;
FILEHEADER rFileHeader;
INFOHEADER rInfoHeader;
IMAGECOMPONENT *pImageData;
int nIsBigEndian = 0, nIsPadByte = 0;
int nImageDataOffset, nWidth, nHeight, nRealWidth;
unsigned char rMax, rMin, gMax, gMin, bMax, bMin;
unsigned long int i, count;
// Check the number of command parameters
if (argc != 2)
{
printf("Incorrect Number Of Command Line Arguments.\n");
exit(0);
}
filename = argv[1];
if ((fp = fopen(filename, "rb")) == NULL)
{
printf("Can't open %s.\n", filename);
exit(0); // open failed and exit
}
if (ReadFileHeader(&rFileHeader, fp) < 0) // get fileheader
{
printf("Read file error.\n");
fclose(fp);
exit(0);
}
if (IsBmpFile((char *)&rFileHeader) == -1)
{
printf("Incorrect File Format.\n");
fclose(fp);
exit(0);
}
nIsBigEndian = IsBigEndian((char *)&rFileHeader);
if (ReadInfoHeader(&rInfoHeader, fp) < 0) // get infoheader
{
printf("Read file error.\n");
fclose(fp);
exit(0);
}
// get imageDataOffset, width, height
nImageDataOffset = (nIsBigEndian == 0) ? rFileHeader.imageDataOffset : ConvertEndianBigToLittle(rFileHeader.imageDataOffset);
nWidth = (nIsBigEndian == 0) ? rInfoHeader.width : ConvertEndianBigToLittle(rInfoHeader.width);
nHeight = (nIsBigEndian == 0) ? rInfoHeader.height : ConvertEndianBigToLittle(rInfoHeader.height);
nIsPadByte = nWidth * 3 % 4; // get pad bytes
nIsPadByte = (nIsPadByte == 0) ? nIsPadByte : (4 - nIsPadByte);
nRealWidth = (nIsPadByte == 0) ? nWidth : (nWidth+1);
pImageData = (IMAGECOMPONENT *)malloc(nRealWidth*nHeight*sizeof(IMAGECOMPONENT));
if (pImageData == NULL)
{
fclose(fp);
exit(0);
}
memset(pImageData, 0, nRealWidth*nHeight*sizeof(IMAGECOMPONENT));
rMax = gMax = bMax = 0;
rMin = gMin = bMin = 255;
count = 0;
// skip image data
fseek(fp, nImageDataOffset, 0);
for (i = 0; i < nRealWidth*nHeight; i++)
{
if ((count == nWidth) && (nIsPadByte != 0))
{
// read pads data
if (ReadImageData(&pImageData[i], nIsPadByte, fp) < 0)
{
printf("Read file error.\n");
free(pImageData);
fclose(fp);
exit(0);
}
count = 0;
}
else
{
count++;
// read real data
if (ReadImageData(&pImageData[i], 3, fp) < 0)
{
printf("Read file error.\n");
free(pImageData);
fclose(fp);
exit(0);
}
rMax = Max(pImageData[i].r, rMax);
rMin = Min(pImageData[i].r, rMin);
gMax = Max(pImageData[i].g, gMax);
gMin = Min(pImageData[i].g, gMin);
bMax = Max(pImageData[i].b, bMax);
bMin = Min(pImageData[i].b, bMin);
}
}
// show info
printf("Image width : %d picture elements\n", nWidth);
printf("Image height : %d picture elements\n", nHeight);
printf("bMax = %-3d\tbMin = %-3d\n", bMax, bMin);
printf("gMax = %-3d\tgMin = %-3d\n", gMax, gMin);
printf("rMax = %-3d\trMin = %-3d\n", rMax, rMin);
free(pImageData);
fclose(fp);
return 1;
}