Files
luban-lite-t3e-pro/packages/artinchip/mpp/mpp_test/ge_test/public/bmp.c
刘可亮 aaa66c7b20 V1.0.1
2023-11-09 20:19:51 +08:00

219 lines
5.1 KiB
C

/*
* Copyright (c) 2022-2023, ArtInChip Technology Co., Ltd
*
* SPDX-License-Identifier: Apache-2.0
*
* Authors: ZeQuan Liang <zequan.liang@artinchip.com>
*/
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <aic_core.h>
#include "bmp.h"
#include "ge_mem.h"
static int cal_bmp_stride(struct bmp_header *bmp_header)
{
int bytes_per_pixel = 0;
if (bmp_header->width <= 0 || bmp_header->bit_count <= 0)
return -1;
bytes_per_pixel = bmp_header->bit_count / 8;
return BYTE_ALIGN((bytes_per_pixel * bmp_header->width), 4);
}
static int cal_stride(struct bmp_header *bmp_header)
{
int bytes_per_pixel = 0;
if (bmp_header->width <= 0 || bmp_header->bit_count <= 0)
return -1;
bytes_per_pixel = bmp_header->bit_count / 8;
return BYTE_ALIGN((bytes_per_pixel * bmp_header->width), 8);
}
static enum bmp_pixel_format bmp_get_ori_fmt(struct bmp_header *bmp_header)
{
if (!bmp_header) {
printf("bmp_header err\n");
return UNKNOWN_FORMAT;
}
switch (bmp_header->bit_count) {
case 1: {
return MONOCHROME_FORMAT;
}
case 4: {
if (bmp_header->compression == 0) {
return INDEXED_4BIT_FORMAT;
} else if (bmp_header->compression == 2) {
return RLE_4BIT_FORMAT;
}
break;
}
case 8: {
if (bmp_header->compression == 0) {
return INDEXED_8BIT_FORMAT;
} else if (bmp_header->compression == 1) {
return RLE_8BIT_FORMAT;
} else if (bmp_header->compression == 2) {
return BITFIELDS_FORMAT;
}
break;
}
case 16: {
if (bmp_header->compression == 0) {
return RGB_565_FORMAT;
} else if (bmp_header->compression == 3) {
return BITFIELDS_FORMAT;
}
break;
}
case 24: {
if (bmp_header->compression == 0) {
return BGR_FORMAT;
}
break;
}
case 32: {
if (bmp_header->compression == 0) {
return BGRA_FORMAT;
} else if (bmp_header->compression == 3) {
return ARGB_FORMAT;
}
break;
}
default: {
printf("format not supported\n");
return UNKNOWN_FORMAT;
}
}
printf("format not supported\n");
return UNKNOWN_FORMAT;
}
enum mpp_pixel_format bmp_get_fmt(struct bmp_header *bmp_header)
{
enum bmp_pixel_format bmp_ori_fmt = 0;
enum mpp_pixel_format mpp_fmt = 0;
bmp_ori_fmt = bmp_get_ori_fmt(bmp_header);
if (bmp_ori_fmt != RGB_565_FORMAT && bmp_ori_fmt != BGR_FORMAT &&
bmp_ori_fmt != BGRA_FORMAT && bmp_ori_fmt != ARGB_FORMAT) {
printf("don't support bmp fmt\n");
return -1;
}
/* change bmp fmt, enable it to display correctly */
switch (bmp_ori_fmt)
{
case BGR_FORMAT:
mpp_fmt = MPP_FMT_RGB_888;
break;
case RGB_565_FORMAT:
mpp_fmt = MPP_FMT_RGB_565;
break;
/* MPP fmt is litte-endian */
case BGRA_FORMAT:
mpp_fmt = MPP_FMT_ARGB_8888;
break;
case ARGB_FORMAT:
mpp_fmt = MPP_FMT_RGBA_8888;
break;
default:
break;
}
return mpp_fmt;
}
int bmp_open(char * path, struct bmp_header *bmp_header)
{
int fd = 0;
fd = open(path, O_RDONLY);
if (fd < 0) {
printf("open bmp fail\n");
return -1;
}
if (read(fd, bmp_header, sizeof(struct bmp_header)) != sizeof(struct bmp_header)) {
printf("read bmp file error \n");
return -1;
}
return fd;
}
void bmp_close(int fd)
{
if (fd > 0)
close(fd);
}
/* read bmp image to the buffers */
int bmp_read(int bmp_fd, void *buffer, struct bmp_header *bmp_header)
{
int i = 0;
int stride = 0;
int bmp_stride = 0;
int height = 0;
unsigned char *buf = NULL;
if (bmp_header->type != 0x4D42) {
printf("not a Bmp file\n");
return -1;
}
if (bmp_fd < 0) {
printf("bmp_fd err\n");
return -1;
}
bmp_stride = cal_bmp_stride(bmp_header);
if (bmp_stride < 0) {
printf("cal bmp stride err\n");
return -1;
}
stride = cal_stride(bmp_header);
if (stride < 0) {
printf("cal stride err\n");
return -1;
}
height = abs(bmp_header->height);
/* read image from bottom to top */
if (bmp_header->height < 0) {
buf = buffer;
for (i = 0; i < height; i++) {
if (read(bmp_fd, buf, bmp_stride) != bmp_stride) {
printf("read bmp to buffer error\n");
return -1;
}
buf += stride;
}
/* read image from top to bottom */
} else {
for (i = height - 1; i >= 0; i--) {
buf = buffer + (i * stride);
if (read(bmp_fd, buf, bmp_stride) != bmp_stride) {
printf("read bmp to buffer error\n");
return -1;
}
}
}
return 0;
}