/* ======================================================================== */
/*  TEXAS INSTRUMENTS, INC.                                                 */
/*                                                                          */
/* ======================================================================== */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "bmp.h"
/****************************************************************************/
/*     读文件bmp                    */
/****************************************************************************/
uint8_t ** read_bmp(char *const filename,bmpfile_header_t *pbf,bmpfile_dib_header_t *pbi,uint8_t **imgdata)
{
	FILE *fp;
	long linebytes = 0;
    long i,j;

	//assert( (filename != NULL) && (pbf != NULL) && (pbi != NULL) );
	if(imgdata != NULL)
	{
		free(imgdata);
		imgdata = NULL;
	}
	fp = fopen("1.bmp","rb");
    if(fp == NULL)
	{
        printf("Open file  error!\n");
        return NULL;
    }

	//读取信息头、文件头
    fread(pbf, sizeof(bmpfile_header_t),1,fp); //把指针fp所指向的文件的头信息写入bf（地址）
    fread(pbi, sizeof(bmpfile_dib_header_t),1,fp);

	//为24位图像数据分配 指针数组空间
    imgdata = (unsigned char**)malloc((sizeof(unsigned char*)) * (pbi->image_height));

    if(pbi->bits_per_pixel == 24)	//24位色
	{
		linebytes = (pbi->image_width * 3 + 3)/4 * 4;   //一行的字节数，应该是4的整数倍
		for ( i=0; i < pbi->image_height; i++)
		{
			imgdata[i] = (unsigned char*)malloc(sizeof(unsigned char) * linebytes);
		}
		for ( i=0;i < pbi->image_height; i++ )  //将bmp图像的位图数据内容逐个字节的读到二维数组中
		{
			for(j=0; j < linebytes; j++)
			{
				fread( &imgdata[i][j], sizeof(unsigned char),1,fp);	//每次只读取一个字节，存入数组
			}
		}
	}
	fclose(fp);   //关闭文件
	return imgdata;
}

/****************************************************************************/
/*     bmp灰度处理图像函数                这里出现的问题就是头文件类型。     */
/****************************************************************************/
jicheng to_gray(bmpfile_header_t *pbf,bmpfile_dib_header_t *pbi,unsigned char **imgdata)
{
	FILE* fp;            //文件指针
	bmpfile_header_t bf; //BMP文件头结构体
	bmpfile_dib_header_t bi; //BMP信息头结构体
	bmp_color_table_t *ipRGB;	     //灰度图像的调色板 256个
	//bmpfile_header_t *CJC;
	unsigned char *gray_data = NULL;//数据
	long i,j;
	long newlinebytes = 0;
	long imagsize = 0;
	long line_start = 0;

	//打开另一个文件，用于写入灰度图像
	if ((fp=fopen("bmp_gray.bmp","wb")) == NULL)
	{
		printf("Open file mybmp.bmp error!");
		exit(0);
	}
#ifdef _DEBUG_BMP
	printf("\n灰度图像文件 bmp_gray.bmp 打开成功！\n");
#endif

	newlinebytes = ( (pbi->image_width+ 3)/4 ) * 4;     //灰度图每行字节数，4的整数倍
	imagsize = newlinebytes * pbi->image_height;         //计算灰度图大小
	memcpy( &bi, pbi, sizeof(bmpfile_dib_header_t) );  //拷贝位图信息头
	bi.bits_per_pixel = 8;							   //灰度图文件像素
	bi.image_size = imagsize;				       //灰度图大小
	bf.signature[1]=0x4D;
	bf.signature[0]=0x42;
	bf.reserved1 = bf.reserved2 = 0;
	bf.bitmap_offset = sizeof(bf) + sizeof(bmpfile_dib_header_t) + 256*sizeof(bmp_color_table_t);
	bf.file_size = pbf->bitmap_offset + imagsize;      //计算灰度图文件大小

	fwrite(&bf, sizeof(bmpfile_header_t),1,fp);   //写入灰度图文件头
	fwrite(&bi, sizeof(bmpfile_dib_header_t),1,fp);   //写入灰度图的信息头

#ifdef _DEBUG_BMP
	printf("灰度图像文件头与信息头写入完成！\n");
#endif
	//创建调色板，初始化 并写入灰度图像文件
	ipRGB = (bmp_color_table_t *)malloc(256 * sizeof(bmp_color_table_t));
	for ( i = 0; i < 256; i++ )
		ipRGB[i].red = ipRGB[i].green = ipRGB[i].blue = (unsigned char)i;
    fwrite(ipRGB,sizeof(bmp_color_table_t),256,fp);		  //写入灰度图的调色板
#ifdef _DEBUG_BMP
	printf("灰度图像调色板写入完成！\n");
#endif
	gray_data = (unsigned char*)malloc(sizeof(unsigned char) * imagsize);
	for ( i=0; i < pbi->image_height; i++ )
	{
		line_start = newlinebytes * i;      //二维数组方式计算i行的首位置
		for ( j = 0; j < newlinebytes; j++ ) //逐个计算灰度图的像素值
		{
			gray_data[line_start + j]= (int)( (float)imgdata[i][3 * j] * 0.114 + \
				(float)imgdata[i][3 * j + 1] * 0.587 + \
				(float)imgdata[i][3 * j + 2] * 0.299 );
		}
	}
    fwrite(gray_data, imagsize, 1, fp);	  //写入灰度图的图像数据
#ifdef _DEBUG_BMP
	printf("灰度图像写入完成！\n");
#endif
	fclose(fp);
	return myTRUE;
}


