BMP图像生成C代码
·
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "../inc/mcip_bmp_utils.h"
/*#define BMP_UTILS_DEBUG*/
/* BMP Gray image default header */
static bmp_header_t default_grayscale_bmp_header = {
{
{'B', 'M'} /*signature*/
},
{
263222, /*file_size*/
0, 0, /*reserved1, reserved2*/
1078 /*bitmap_offset*/
},
{
40, /*header_size*/
512, /*width*/
512, /*height*/
1, /*nplanes*/
8, /*bitspp*/
0, /*compress_type*/
262144, /*bmp_bytesz*/
0, /*hres*/
0, /*vres*/
256, /*ncolors*/
0 /*nimpcolors*/
}
};
/****************************************************************************/
/* Bitmap header reading routine */
/****************************************************************************/
int bmp_read_header (raw_image_data_t * image, bmp_header_t * hdr)
{
if (image->length <
sizeof(bmpfile_signature_t) + sizeof(bmpfile_header_t) + sizeof(bmpfile_dib_header_t)) {
printf ("Insufficient Image Buffer Length %d\n", image->length);
return -1;
}
memcpy(&(hdr->signature), image->data, sizeof(bmpfile_signature_t));
memcpy(&(hdr->file), image->data + sizeof(bmpfile_signature_t),
sizeof(bmpfile_header_t));
memcpy(&(hdr->dib), image->data + sizeof(bmpfile_signature_t) + sizeof(bmpfile_header_t),
sizeof(bmpfile_dib_header_t));
#if BMP_UTILS_DEBUG
printf("signature = %c%c\n", hdr->signature.signature[0], hdr->signature.signature[1]);
printf("header.file_size = %d\n", hdr->file.file_size);
printf("header.reserved1 = %d\n", hdr->file.reserved1);
printf("header.reserved2 = %d\n", hdr->file.reserved2);
printf("header.bitmap_offset = %d\n", hdr->file.bitmap_offset);
printf("info_header.header_size = %d\n", hdr->dib.header_size);
printf("info_header.width = %d\n", hdr->dib.image_width);
printf("info_header.height = %d\n", hdr->dib.image_height);
printf("info_header.nplanes = %d\n", hdr->dib.number_of_planes);
printf("info_header.bitspp = %d\n", hdr->dib.bits_per_pixel);
printf("info_header.compress_type = %d\n", hdr->dib.compression_type);
printf("info_header.bmp_bytesz = %d\n", hdr->dib.image_size);
printf("info_header.hres = %d\n", hdr->dib.horizontal_resolution);
printf("info_header.vres = %d\n", hdr->dib.vertical_resolution);
printf("info_header.ncolors = %d\n", hdr->dib.number_of_colors);
printf("info_header.nimpcolors = %d\n", hdr->dib.important_color_count);
#endif
if((hdr->signature.signature[0] != 'B') || (hdr->signature.signature[1] != 'M')) {
printf("Incorrect MAGIC number 0x%x 0x%x\n", hdr->signature.signature[0], hdr->signature.signature[1]);
return -1;
}
if((hdr->dib.bits_per_pixel != 8) && (hdr->dib.bits_per_pixel != 24)) {
printf("Only 8 or 24 bits per pixel supported, the image bpp is %d\n", hdr->dib.bits_per_pixel);
return -1;
}
if(hdr->dib.compression_type != BMP_RGB) {
printf("Need a RGB type image, the image type is %d\n", hdr->dib.compression_type);
return -1;
}
return 0;
}
/****************************************************************************/
/* Bitmap colormap reading routine */
/****************************************************************************/
int bmp_read_colormap (raw_image_data_t * image, bmp_header_t * hdr,
bmp_color_table_t * color_table)
{
int index;
if(hdr->dib.number_of_colors == 0) {
printf("Color table can't be read, ncolors = %d\n", hdr->dib.number_of_colors);
return -1;
}
index = sizeof(bmpfile_signature_t) + sizeof(bmpfile_header_t) + hdr->dib.header_size;
memcpy(color_table, image->data + index, sizeof(bmp_color_table_t) * hdr->dib.number_of_colors);
#if BMP_UTILS_DEBUG
{
int i;
printf("Color Table:\nindex:\tblue\tgreen\tred\n");
for (i = 0; i < hdr->dib.number_of_colors; i++){
printf("%d:\t0x%02x\t0x%02x\t0x%02x\n",
i, color_table[i].blue, color_table[i].green, color_table[i].red);
}
}
#endif
return 0;
}
/****************************************************************************/
/* Bitmap image row reading routine */
/****************************************************************************/
int bmp_read_image (raw_image_data_t * image, bmp_header_t * hdr, uint8_t * pixel_array_rgb)
{
int i;
int index;
int pixel_size = hdr->dib.bits_per_pixel / 8;
int row_width = hdr->dib.image_width * pixel_size;
int row_width_with_pad = ((row_width) + 3) & (~3);
for(i = 0; i < hdr->dib.image_height; i++) {
index = hdr->file.bitmap_offset + (row_width_with_pad * (hdr->dib.image_height - i - 1));
memcpy(pixel_array_rgb + (i * row_width), image->data + index, row_width);
#if BMP_UTILS_DEBUG
if (i == 0) {
int j, k;
printf("Pixel Value (0): ");
for(j = 0; j < 512; j++){
for(k = 0; k < pixel_size; k++) {
printf("%x", (uint8_t)*(pixel_array_rgb + (i * row_width) + (j * pixel_size) + k));
}
printf(" ");
}
printf("\n");
}
#endif
}
return 0;
}
/****************************************************************************/
/* Write a gray scale image file */
/****************************************************************************/
int bmp_write_gray_bmpfile (raw_image_data_t * image, uint8_t * pixel_array,
uint32_t width, uint32_t height)
{
int i;
int index = 0;
int row_width_with_pad = (width + 3) & (~3);
int pad_size = row_width_with_pad - width;
bmp_color_table_t * color_table = 0;
uint8_t * pad_array = 0;
bmp_header_t hdr = default_grayscale_bmp_header;
int ret_val = 0;
if(pad_size) {
pad_array = calloc(pad_size, 1);
}
hdr.dib.image_height = height;
hdr.dib.image_width = width;
hdr.dib.image_size = (row_width_with_pad * hdr.dib.image_height);
color_table = calloc(sizeof(bmp_color_table_t), hdr.dib.number_of_colors);
for(i = 0; i < hdr.dib.number_of_colors; i++) {
color_table[i].blue = i;
color_table[i].green = i;
color_table[i].red = i;
}
hdr.file.file_size =
sizeof(bmpfile_signature_t) + sizeof(bmpfile_header_t)
+ hdr.dib.header_size
+ (sizeof(bmp_color_table_t) * hdr.dib.number_of_colors)
+ (row_width_with_pad * hdr.dib.image_height);
hdr.file.bitmap_offset =
sizeof(bmpfile_signature_t)
+ sizeof(bmpfile_header_t) + hdr.dib.header_size
+ (sizeof(bmp_color_table_t) * hdr.dib.number_of_colors);
if (image->length < hdr.file.file_size) {
printf("Insufficient image array size %d (expected %d)",
image->length, hdr.file.file_size);
ret_val = -1;
goto close_n_exit;
}
memcpy(image->data, &hdr.signature, sizeof(bmpfile_signature_t));
index = sizeof(bmpfile_signature_t);
memcpy(image->data + index, &hdr.file, sizeof(bmpfile_header_t));
index += sizeof(bmpfile_header_t);
memcpy(image->data + index, &hdr.dib, sizeof(bmpfile_dib_header_t));
index += sizeof(bmpfile_dib_header_t);
memcpy(image->data + index, color_table, sizeof(bmp_color_table_t) * hdr.dib.number_of_colors);
index += sizeof(bmp_color_table_t) * hdr.dib.number_of_colors;
for(i = hdr.dib.image_height - 1; i >= 0; i--) {
memcpy(image->data + index, pixel_array + (hdr.dib.image_width * i), hdr.dib.image_width);
index += hdr.dib.image_width;
if (pad_size) {
memcpy(image->data + index, pad_array, pad_size);
index += pad_size;
}
}
ret_val = 0;
close_n_exit:
if(color_table) free(color_table);
if(pad_array) free(pad_array);
return ret_val;
}
/****************************************************************************/
/* Get a gray scale image file file size */
/****************************************************************************/
uint32_t bmp_get_gray_bmpfile_size (uint32_t width, uint32_t height)
{
int row_width_with_pad = (width + 3) & (~3);
bmp_header_t hdr = default_grayscale_bmp_header;
return(sizeof(bmpfile_signature_t) + sizeof(bmpfile_header_t)
+ hdr.dib.header_size
+ (sizeof(bmp_color_table_t) * hdr.dib.number_of_colors)
+ (row_width_with_pad * height));
}
#ifndef BMP_UTILS_H
#define BMP_UTILS_H
#include <stdint.h>
/****************************************************************************/
/* Bitmap header structure */
/****************************************************************************/
#ifdef _HOST_BUILD
#pragma pack(1)
#endif
typedef struct bmpfile_signature {
uint8_t signature[2]; /* Signature - 'BM' */
} bmpfile_signature_t;
typedef struct bmpfile_header {
uint32_t file_size; /* File size in bytes */
uint16_t reserved1;
uint16_t reserved2;
uint32_t bitmap_offset; /* Offset to bitmap */
} bmpfile_header_t;
typedef struct bmpfile_dib_header {
uint32_t header_size; /* Size of this struct */
int32_t image_width; /* Image width in pixels */
int32_t image_height; /* Image image_height in pixels */
uint16_t number_of_planes; /* Number of planes */
uint16_t bits_per_pixel; /* Bits per pixel */
uint32_t compression_type;/* Compression flag */
uint32_t image_size; /* Image size in bytes */
int32_t horizontal_resolution; /* Horizontal resolution */
int32_t vertical_resolution; /* Vertical resolution */
uint32_t number_of_colors; /* Color map size */
uint32_t important_color_count; /* Important color count */
} bmpfile_dib_header_t;
typedef struct bmp_header {
bmpfile_signature_t signature;
bmpfile_header_t file;
bmpfile_dib_header_t dib;
} bmp_header_t;
/****************************************************************************/
/* Bitmap RGB colormap entry structure */
/****************************************************************************/
typedef struct {
uint8_t red;
uint8_t green;
uint8_t blue;
uint8_t reserved;
} bmp_color_table_t;
#ifdef _HOST_BUILD
#pragma pack()
#endif
typedef enum {
BMP_RGB = 0,
BMP_RLE8,
BMP_RLE4,
BMP_BITFIELDS,
BMP_JPEG,
BMP_PNG
} bmp_compression_method_e;
/* Raw image data
*/
typedef struct raw_image_data {
uint8_t * data;
uint32_t length;
} raw_image_data_t;
/* This function reads the header information from a bitmap file.
* Note: It also does some preliminary checking if the file is valid.
* It would return 0 for success and < 0 if file read or check fails.
*/
extern int bmp_read_header (raw_image_data_t * image, bmp_header_t * hdr);
/* This function reads the color table from the file.
* It should be called if info_header.ncolors > 0.
* The color_table structure should be an array of bmp_color_table_t size
* length hdr->dib.ncolors.
*/
extern int bmp_read_colormap (raw_image_data_t * image, bmp_header_t * hdr,
bmp_color_table_t * color_table);
/* This function reads the image (or pixel value). It expects the pixel_array_rgb should
* be of size [hdr->dib.height * (hdr->dib.width * hdr->dib.bitspp / 8)], i.e., image size
* in bytes.
*/
extern int bmp_read_image (raw_image_data_t * image, bmp_header_t * hdr, uint8_t * pixel_array_rgb);
/* This function creates and writes a gray scale image to system.
* It expects the pixel_array should be of size
* [hdr->dib.height * (hdr->dib.width * hdr->dib.bitspp / 8)],
* i.e., image size in bytes.
*/
extern int bmp_write_gray_bmpfile (raw_image_data_t * image, uint8_t * pixel_array,
uint32_t width, uint32_t height);
/*
* Get a gray scale image file file size
*/
extern uint32_t bmp_get_gray_bmpfile_size (uint32_t width, uint32_t height);
#endif /*BMP_UTILS_H*/
魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐


所有评论(0)