回 帖 发 新 帖 刷新版面

主题:菜鸟求助    关于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;
}

回复列表 (共1个回复)

沙发

先把自己的代码梳理一下,请人帮忙也要把注释加上吧!太长了

我来回复

您尚未登录,请登录后再回复。点此登录或注册