www.pudn.com > Hough.rar > BMP.cpp
#include "stdafx.h" #include#include "BMPFormat.h" /************************************************************************************** * 函数名:ReadBinaryBMP * 功能:读二值BMP图像 * 说明:1、从fullfilename文件中读取数据,把BMP头赋给headBMP, 把信息头赋给infoHead, * 把调色板数据读到pRgbPlates指定的内存块中, * 把图像数据读到pImgData指定的内存块中,图像数据的个数为dataCount, * 把剩余数据读到pLeftData指定的内存块中,剩余数据的个数为leftDataCount, * 出错信息赋给errorMsg, 状态信息赋给info 。 * 2、在本函数内用malloc()函数分别为调色板、图像数据、其余数据分配了内存, * 并把相应指针赋给pRgbPlates、pImgData、pLeftData,在函数外部的适当地方 * 应该用free()释放pRgbPlates、pImgData、pLeftData指向的内存。 * 输入参数: * fullfilename --- 带路径的BMP文件名 * 输出参数: * headBMP --- BMP头 * infoHead --- 信息头 * pRgbPlates --- 指向调色板 * rgbPlateDataCount --- 调色板所占的字节数 (对于8位图像,应该有256个调色板项,每项4个字节) * pImgData --- 指向图像数据内存块 * dataCount --- 图像数据所占的字节数 * pLeftData --- 图像文件中多余的字节数据 * leftDataCount --- 图像文件中多余的字节个数 * errorMsg --- 错误信息 * info --- 非错误信息 * 返回值: * 未发生错误,返回TRUE; 发生错误,返回FALSE; * 当返回TRUE时,info中存放的是函数执行过程中的状态信息。 * 当返回FALSE时,errorMsg中存放的是函数执行过程中的出错信息。 ****************************************************************************************/ BOOL ReadBinaryBMP(CString fullfilename, BmpHead& headBMP, InfoHead& infoHead, BYTE*& pRgbPlates, long& rgbPlateDataCount, BYTE*& pImgData, long& dataCount, /*BYTE*& pLeftData, long& leftDataCount, */ CString& errorMsg, CString& info) { // BmpHead headBMP; // InfoHead infoHead; FILE* p; p = fopen(fullfilename,"rb"); if (p == NULL) { errorMsg.Format("*** Error: file %s open failed! *** \n", fullfilename); return FALSE; } info.Format("file %s open success.\n",fullfilename); /********** read BMP head ********************/ WORD mark; fread(&mark,1,2,p); //fseek(p,2,SEEK_CUR); if(mark != 19778) //'BM' { errorMsg = "*** Error: the picture is not of the format of bmp! *** \n"; return FALSE; } fread(&headBMP,1,12,p); //headBMP.show(); CString msg; msg.Format("Image Size:%d \n",headBMP.imageSize); info += msg; msg.Format("Image Data Start Position : %d \n",headBMP.startPosition); info += msg; fread(&infoHead,1,40,p); if (infoHead.bitColor != 8) { fclose(p); errorMsg.Format("*** Error: This is not a picture of 8 bits *** \n"); return FALSE; } if (infoHead.height > 0) { // 倒向图像,图像数据存储从左到右,从下至上,即从左下角到右上角。大部分bmp图像都是倒向图像 msg.Format("Normal Image, That is, \n The pixel data is stored from left to right, from bottom to top. \n"); } else { // 正向图像,图像数据存储从左到右,从上到下,即从左上角到右下角 msg.Format("Special Image, That is, \n The pixel data is stored form left to right, from top to bottom. \n"); } info += msg; msg.Format("Image Size : %d * %d \n", infoHead.width, infoHead.height); info += msg; if ((infoHead.width % 4) != 0) { // 当infoHead.width不是4的倍数时,在保存图像数据到文件中时,每一行的最后要补充0,使每一行的字节数为4的倍数。 msg.Format("The image width is not the multiple of 4, \n so that zeros will be added at each end of the image row. \n"); info += msg; } else { msg.Format("The image width is the multiple of 4, \n so that no zero was added at end of each row. \n"); } /*********** read Palette **************/ rgbPlateDataCount = 256 * sizeof(RGBMixPlate); // 256个调色板项,每项4个字节 pRgbPlates = new BYTE[rgbPlateDataCount]; fread(pRgbPlates, 1, rgbPlateDataCount, p); /*********** read Image Date **************/ if ((infoHead.realSize != 0) && ((infoHead.width % 4) == 0)) { dataCount = infoHead.realSize; } else // infoHead.realSize == 0 或 (infoHead.width % 4) != 0 { dataCount = infoHead.width * infoHead.height * (infoHead.bitColor/8); } pImgData = new BYTE[dataCount]; if (infoHead.width % 4 == 0) // 宽度(以像素计)是4的倍数,则图像数据区中的每一行末尾不用添加0 { fread(pImgData, 1, dataCount, p); // 直接把所有数据读进内存 msg.Format("No zero need to be added at end of row. \n Image data have been read at one time. \n"); info += msg; } else // 宽度(以像素计)不是4的倍数,则图像数据区中的每一行末尾要添加0,使每行的像素数是4的倍数 { // 在图像数据的每一行末尾要添加0的个数(以像素为单位) int nAddedZerosCount = (infoHead.width/4 + 1) * 4 - infoHead.width; msg.Format("At each end of row, %d byte of zeros have been added. \n", nAddedZerosCount); info += msg; for (int i=0; i