从bmp文件的标题中读取

问题描述 投票:-1回答:2

我正在编写程序以读取bmp标头。我编写了一些在main中都可用的代码。如何实现此代码本身的功能,然后将其实现到main上?

这里是整个代码:

#include <stdio.h> 
#include <stdlib.h> 
#include <stdio.h> 
#include <stdin.h> 

struct bmp_header { 
    uint16_t type; 
    uint32_t size; 
    uint16_t reserved1;     
    uint16_t reserved2;    
    uint32_t offset;        
    uint32_t dib_size;  
    uint32_t width;         
    uint32_t height;        
    uint16_t planes;       
    uint16_t bpp;            
    uint32_t compression;    
    uint32_t image_size;    
    uint32_t x_ppm;         
    uint32_t y_ppm;          
    uint32_t num_colors;     
    uint32_t important_colors; 
}; 


void read_bmp(FILE *BMPFile,struct bmp_header* Header) {  
    fread(&(Header->type), 2, 1, BMPFile); 
    fread(&(Header->size),4,1,BMPFile); 
    fread(&(Header->reserved1),2,1,BMPFile); 
    fread(&(Header->reserverd2),2,1,BMPFile); 
    fread(&(Header->offset),4,1,BMPFile); 
    fread(&(Header->dib_size),4,1,BMPFile); 
    fread(&(Header->width),4,1,BMPFile); 
    fread(&(Header->height),4,1,BMPFile); 
    fread(&(Header->planes),2,1,BMPFile); 
    fread(&(Header->bpp),2,1,BMPFile); 
    fread(&(Header->compression),4,1,BMPFile); 
    fread(&(Header->image_size),4,1,BMPFile); 
    fread(&(Header->x_ppm),4,1,BMPFile); 
    fread(&(Header->y_pp),4,1,BMPFile); 
    fread(&(Header->num_colors),4,1,BMPFile); 
    fread(&(Header->important_colors),4,1,BMPFile); 
} 

int main() { 
    FILE *BMPFile = fopen("image.bmp","rb"); 
    if(BMPFile == NULL) 
    { 
        return; 
    } 

    struct bmp_header* Header; 
    read_bmp(BMPFile,Header); 
    fclose(BMPFile); 

    return 0; 
} 

该程序版本的相关部分以及在main中的所有读取操作均按预期工作,在下面报告,

int main( void )
{
    FILE *BMPFile = fopen ("lenna.bmp", "rb");

    if (BMPFile == NULL)
    {
        return 0;
    }

    struct bmp_header Header;

    memset(&Header, 0, sizeof(Header));

    fread(&Header.type, 2, 1, BMPFile);
    fread(&Header.size),4,1,BMPFile); 
    fread(&Header.reserved1),2,1,BMPFile); 
    fread(&Header.reserverd2),2,1,BMPFile); 
    fread(&Header.offset),4,1,BMPFile); 
    fread(&Header.dib_size),4,1,BMPFile); 
    fread(&Header.width),4,1,BMPFile); 
    fread(&Header.height),4,1,BMPFile); 
    fread(&Header.planes),2,1,BMPFile); 
    fread(&Header.bpp),2,1,BMPFile); 
    fread(&Header.compression),4,1,BMPFile); 
    fread(&Header.image_size),4,1,BMPFile); 
    fread(&Header.x_ppm),4,1,BMPFile); 
    fread(&Header.y_pp),4,1,BMPFile); 
    fread(&Header.num_colors),4,1,BMPFile); 
    fread(&Header.important_colors),4,1,BMPFile);

    /* Header fields print section */
    /* ...                         */
}
c pointers struct bmp
2个回答
0
投票

您必须创建struct bmp_header *类型的函数。接下来,在函数中创建struct bmp_header指针,并为返回的引用分配内存(头大小== 54B)。


0
投票

无论何时工作代码停止工作,集中精力在代码的两个版本之间的更改会很有用。那么,为什么您的原始代码可以正常工作?看起来像这样:

int main( void )
{
    FILE *BMPFile = fopen ("lenna.bmp", "rb");

    if (BMPFile == NULL)
    {
        return 0;
    }

    struct bmp_header Header;

    memset(&Header, 0, sizeof(Header));

    fread(&Header.type, 2, 1, BMPFile);
    ...
}
  1. 您在main的堆栈中声明为Header类型的struct bmp_header(作为局部变量)。 通过这种方式,可以确定在程序的整个生命周期中分配结构
  2. 您将memset设为0
  3. 您将Header的字段地址直接传递给fread

在新版本的程序中,您定义的功能为

void read_bmp(FILE *BMPFile,struct bmp_header* Header);

所以您需要一个指向struct bmp_header的指针才能传递给它。因此,您声明

struct bmp_header *标头;

并呼叫read_bmp(BMPFile,Header);

工作版本有什么不同?好吧,指针!声明一个指向编译器的指针,该指针包含一个地址,在本例中为read_bmp()所需结构的地址。

但是您从不向编译器说地址是什么,以便fread中的read_bmp()将写入随机位置,从而导致分段错误。


怎么办

您需要将[ read_bmp()地址传递给struct bmp_header,并且您具有两个选项。

    您可以像以前一样在堆栈中分配Header,并通过read_bmp()运算符将其地址传递给&。这应该是您的第一次尝试,因为它确实与您的工作解决方案相似。
  • struct bmp_header Header; read_bmp(BMPFile, &Header);
      您可以将Header声明为指针,但是您将需要通过malloc动态分配其内存:
  • struct bmp_header * Header = malloc(sizeof(struct bmp_header)); read_bmp(BMPFile, Header);
  • © www.soinside.com 2019 - 2024. All rights reserved.