Linux上Fread读取长度不对的问题

背景

读取BMP文件的数据,并将数据存储到申请到的data buffer中。

问题

BMP格式中的biSizeImage 字段指示后面的data的总长度,只需要按照这个长度读取data 就可以了;但是读取的图片始终是少一部分;如下图;

程序代码:

typedef unsigned long DWORD; // 四个字节
typedef int BOOL;
typedef unsigned char BYTE;	 // 一个字节
typedef unsigned short WORD; // 一个字节
// 位图信息头结构体定义
typedef struct tagBITMAPINFOHEADER
{
	WORD bfType; // 两个字节
	DWORD bfileSize;
	DWORD bfReserved;
	DWORD bOffBits;
	DWORD biSize; // 4个字节
	long biWidth; // 4个字节
	long biHeight;
	WORD biPlanes;
	WORD biBitCount;
	DWORD biCompression;
	DWORD biSizeImage;
	long biXPelsPerMeter;
	long biYPelsPerMeter;
	DWORD biClrUsed;
	DWORD biClrImportant;
} __attribute__((packed)) BITMAPINFOHEADER, *PBITMAPINFOHEADER; // 字节对齐
typedef struct
{
	BITMAPINFOHEADER header; // 信息头
	char *data;				 // 图像数据
} bmp_t;

int main(void)
{
	char *InputName, *OutputName; // 输入输出图像文件名变量
	FILE *InputFile, *OutputFile; // 输入输出图像文件
	bmp_t *bmp = NULL, *blur = NULL;
	InputName = "test06.bmp";
	OutputName = "output.bmp";
	if (!(InputFile = fopen(InputName, "b"))) // 图像文件打开函数,打不开返回,提示找不到文件
	{
		printf("File not found\n");
		return 1;
	}
	bmp = bmp_open(InputFile);	// 图像文件读取操作,前面必须有打开的操作才能读取文件数据
	fclose(InputFile);					  // 关闭文件

    ...  ...

};
bmp_t *bmp_open(FILE *f)
{
	bmp_t *bmp;
	bmp = (bmp_t *)malloc(sizeof(bmp_t));
	bmp->data = NULL;

	size_t num = 0;
	if (num = fread(&(bmp->header), sizeof(BITMAPINFOHEADER), 1, f))
	{
		bmp->data = (char *)malloc(bmp->header.biSizeImage + 54 );
		memset(bmp->data, 0, bmp->header.biSizeImage);
		//lseek(f,0,SEEK_SET);
		num = fread(bmp->data, bmp->header.biSizeImage, 1, f);// 问题:始终没有读取到指定长度的数据
		if (feof(f))
		{
			printf("文件已到达末尾。\n");
		}
		else if (ferror(f))
		{
			printf("读取错误发生。\n");
			// 清除错误状态
			clearerr(f);
		}
		else if (num == 0 && !feof(f))
		{
			printf("未知错误, fread返回0。\n");
		}
		if (num)
			printf("\n图像读取成功\n");
		
		printf("===> num %d\n", num); // 问题: num 一直返回为0!!!!!

		printf("sizeof(BITMAPINFOHEADER) %d\n", sizeof(BITMAPINFOHEADER));
		printf("Width: %ld\n", bmp->header.biWidth);
		printf("Height: %ld\n", bmp->header.biHeight);
		printf("BitCount: %d\n\n", (int)bmp->header.biBitCount);
		printf("biSizeImage: %x\n\n", (int)bmp->header.biSizeImage);
		return bmp;
	}
	fprintf(stderr, "Error reading file");
	bmp_free(bmp);
	return NULL;
}

原因:

文件的打开是以“r” 的模式打开,需要以“rb” 模式打开二进制文件。

if (!(InputFile = fopen(InputName, "rb"))) // 图像文件打开函数,打不开返回,提示找不到文件
	{
		printf("File not found\n");
		return 1;
	}

注意事项

为啥我读取长度没有达到文件data的长度,图片的上半部分会出现数据缺失问题,而不是下半部分出现缺失?原因是BMP格式的文件是从左往右,从下到上扫描的,所以data offset比较小的地方数据是存在图片的下半部分。

  • 9
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值