读取bmp标题

问题描述 投票:0回答:1

这是我的 BMP 文件头结构

#ifndef _BMP_H
#define _BMP_H

#include <stdint.h>
#include <stdio.h>
#include <stdbool.h>


#define PADDING_CHAR "\0"

/**
 * Structure contains information about the type, size, layout, dimensions
 * and color format of a BMP file. Size of structure is 54 bytes.
*/
struct bmp_header{
    uint16_t type;              // "BM" (0x42, 0x4D)
    uint32_t size;              // file size
    uint16_t reserved1;         // not used (0)
    uint16_t reserved2;         // not used (0)
    uint32_t offset;            // offset to image data (54B)
    uint32_t dib_size;          // DIB header size (40B)
    uint32_t width;             // width in pixels
    uint32_t height;            // height in pixels
    uint16_t planes;            // 1
    uint16_t bpp;               // bits per pixel (1/4/8/24)
    uint32_t compression;       // compression type (0/1/2) 0
    uint32_t image_size;        // size of picture in bytes, 0
    uint32_t x_ppm;             // X Pixels per meter (0)
    uint32_t y_ppm;             // X Pixels per meter (0)
    uint32_t num_colors;        // number of colors (0)
    uint32_t important_colors;  // important colors (0)
} __attribute__((__packed__));

/**
 * Reads BMP header from input stream
 *
 * Reads and returns BMP header from opened input stream. The header is located
 * at it's beginning. If the stream is not opened or it is corrupted, function
 * returns `NULL`.
 *
 * @param stream opened stream, where the image data are located
 * @return `bmp_header` structure or `NULL`, if stream is not open or broken
 */
struct bmp_header* read_bmp_header(FILE* stream);

这是我的代码,它读取 bmp 标题

#include <stdio.h>
#include <stdint.h>
#include <ctype.h>
#include "bmp.h"
#include <string.h>
#include <stdlib.h>
#include <math.h>

struct bmp_header* read_bmp_header(FILE* stream){
    //проверка на успешное открытие файла
        if(stream == NULL) return NULL;
    

    //создание структуры для хранения заголовка БМП
    struct bmp_header* header = (struct bmp_header*)malloc(sizeof(struct bmp_header));
    if(header == NULL) return NULL;

    //проверка на чтение даных заголовка файла
    size_t succes_read = fread(header, sizeof(struct bmp_header), 1, stream);
    
    if(succes_read != 1){
        free(header);
        return NULL;
    }
    
    if(header->type != 0x4D42 || header->width <= 0 || header->height <= 0 || header->offset != 54 || header->dib_size != 40 || header->planes != 1 || (header->bpp != 1 && header->bpp != 4 && header->bpp != 8 && header->bpp != 24) || header->compression != 0 || header->image_size == 0 || header->x_ppm != 0 || header->y_ppm != 0 || header->num_colors != 0 || header->important_colors != 0){
        free(header);
        return NULL;
    }

    if(header->width > UINT32_MAX || header->height > UINT32_MAX){
        free(header);
        return NULL;
    }

    return header;
}

我的问题是,当机器人检查我的代码和这个函数时,他会执行此检查“给定有效的 BMP 流,当调用函数时,图像宽度必须有效,图像高度必须有效”,并且 idk 我需要什么做。

我尝试检查宽度和高度,但此代码不适用于我编写的检查。如果有人知道我需要做什么,请帮助我。

c image bmp
1个回答
1
投票

问题可能与

read_bmp_header
函数中图像宽度和高度的验证条件有关。让我们重新审视您的代码:

if(header->type != 0x4D42 || header->width <= 0 || header->height <= 0 || header->offset != 54 || header->dib_size != 40 || header->planes != 1 || (header->bpp != 1 && header->bpp != 4 && header->bpp != 8 && header->bpp != 24) || header->compression != 0 || header->image_size == 0 || header->x_ppm != 0 || header->y_ppm != 0 || header->num_colors != 0 || header->important_colors != 0){
    free(header);
    return NULL;
}

if(header->width > UINT32_MAX || header->height > UINT32_MAX){
    free(header);
    return NULL;
}

您的第一个条件检查

header->width
header->height
是否小于或等于 0,但 BMP 图像可以具有正尺寸。相反,您应该验证它们是否在合理范围内。

试试这个:

if(header->type != 0x4D42 || header->width == 0 || header->height == 0 || header->offset != 54 || header->dib_size != 40 || header->planes != 1 || (header->bpp != 1 && header->bpp != 4 && header->bpp != 8 && header->bpp != 24) || header->compression != 0 || header->image_size == 0 || header->x_ppm != 0 || header->y_ppm != 0 || header->num_colors != 0 || header->important_colors != 0){
    free(header);
    return NULL;
}

if(header->width > UINT32_MAX || header->height > UINT32_MAX){
    free(header);
    return NULL;
}

这些更改将确保宽度和高度是正且合理的值。如果标头通过这些条件,那么它应该被视为有效。

© www.soinside.com 2019 - 2024. All rights reserved.