⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 imfile.cpp

📁 这是个人脸识别程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// $image\imfile.cpp 1.5 milbo$ image file io// Warning: this is raw research code -- expect it to be quite messy.// milbo durban dec05#include <windows.h>#include <io.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <time.h>#include <signal.h>#include <float.h>#include <math.h>#include <new.h>#include <direct.h>#include <sys/stat.h>#include <fstream.h>#include <iostream.h>#include "mcommon.hpp"#include "mfile.hpp"#include "image.hpp"#include "imutil.hpp"#include "rgbimutil.hpp"#include "imfile.hpp"#include "jpegutil.hpp"void __cdecl SysErr(const char *pArgs, ...);					// args like printfvoid __cdecl Err(const char *pArgs, ...);void __cdecl bprintf(bool fBrief, const char *pArgs, ...);void __cdecl lprintf(const char *pArgs, ...);static char	sgErr[256]; // place to store error messages//-----------------------------------------------------------------------------// Load a .bmp file.  See the header of sLoadImage for some details.static char *sLoadBmp (Image *pImg, RgbImage *pRgbImg, 														// out						const char *sPath, bool fExitOnErr, bool fRemovePad=true, bool fDeleteOnErr=false)	// in{BITMAPFILEHEADER 	bmfHeader;BITMAPINFOHEADER 	bmiHeader;FILE				*pBmpFile;pBmpFile = fopen(sPath, "rb");if (!pBmpFile)	{	if (fDeleteOnErr)		unlink(sPath);			if (fExitOnErr)		Err("Can't open %s", sPath);	else		{		sprintf(sgErr, "Can't open %s", sPath);		return sgErr;		}	}unsigned Len;if ((Len = fread(&bmfHeader, 1, sizeof(bmfHeader), pBmpFile)) != sizeof(bmfHeader) ||		fread(&bmiHeader, 1, sizeof(bmiHeader), pBmpFile) != sizeof(bmiHeader))	{	if (fDeleteOnErr)		unlink(sPath);			if (fExitOnErr)		Err("Can't read %s%s", sPath, (Len? " (too short to be a BMP file)": ""));	else		{		sprintf(sgErr, "Can't read %s%s", sPath, (Len? " (too short to be a BMP file)": ""));		fclose(pBmpFile);		return sgErr;		}	}if (bmfHeader.bfType != ((WORD) ('M' << 8) | 'B'))	{	if (fDeleteOnErr)		unlink(sPath);			if (fExitOnErr)		Err("%s is not a BMP file (first two chars are not \"BM\")", sPath);	else		{		sprintf(sgErr, "%s not a BMP file (first two chars are not \"BM\")", sPath);		fclose(pBmpFile);		return sgErr;		}	}if (bmiHeader.biClrUsed || bmiHeader.biBitCount != 24 || bmiHeader.biCompression)	{	if (fDeleteOnErr)		unlink(sPath);			if (fExitOnErr)		Err("%s is not a windows 24 bit uncompressed RGB file", sPath);	else		{		sprintf(sgErr, "%s not a windows 24 bit uncompressed RGB file", sPath);		fclose(pBmpFile);		return sgErr;		}	}int width = bmiHeader.biWidth;int height = bmiHeader.biHeight;if (width < 0 || width > CONF_nMaxImageDim || height > CONF_nMaxImageDim || height < 0)	{	if (fDeleteOnErr)		unlink(sPath);			if (fExitOnErr)		Err("%s has a strange width %d or height", sPath, width, height);	else		{		sprintf(sgErr, "%s has a strange width %d or height", sPath, width, height);		fclose(pBmpFile);		return sgErr;		}	}int nPad = width % 4;Len = (((3 * width) + nPad) * height);byte *pRgbTemp = (byte *)malloc(Len);	// have to use a temporary buffer because of padif (fread(pRgbTemp, 1, Len, pBmpFile) != Len)	{	free(pRgbTemp);	if (fDeleteOnErr)		unlink(sPath);			if (fExitOnErr)		Err("Can't read %s (it's shorter than its header says it should be)", sPath);	else		{		sprintf(sgErr, "Can't read %s (it's shorter than its header says it should be)", sPath);		fclose(pBmpFile);		return sgErr;		}	}fclose(pBmpFile);if (pImg)	{	// copy pRgbTemp into pImg, converting to gray and discarding the pad	pImg->dim(width, height);	byte *pTo = pImg->buf;	for (int iy = height - 1; iy >= 0; iy--)		{		byte *pFrom = pRgbTemp + (3 * iy * width) + (nPad * iy);		for (int ix = 0; ix < width; ix++)			{			tRGB Rgb = *(tRGB *)pFrom;			*pTo++ = (byte)RgbToGray(Rgb); 	// CIE conversion to gray			pFrom += 3;			}		}	}if (pRgbImg)	{	// copy pRgbTemp into pRgbImg, discarding the nasty little pad	pRgbImg->dim(width + (fRemovePad? 0: nPad), height);	tRGB *pTo = pRgbImg->buf;	tRGB *pFrom = (tRGB *)pRgbTemp;	for (int iy = 0; iy < height; iy++)		{		for (int ix = 0; ix < width; ix++) 			*pTo++ = *pFrom++;		byte *r = (byte *)pFrom;		r += nPad;		pFrom = (tRGB *)r;		}	}free(pRgbTemp);return NULL;	// success}//-----------------------------------------------------------------------------// Load a .pgm file.  See the header of sLoadImage for some details.static char *sLoadPgm (Image *pImg, RgbImage *pRgbImg, 	// out			   const char *sPath, bool fExitOnErr)		// in{FILE *pFile = fopen(sPath, "rb");if (!pFile)	if (fExitOnErr)		Err("Can't open %s", sPath);	else		{		sprintf(sgErr, "Can't open %s", sPath);		return sgErr;		}int width=-1, height=-1, DataSize, nTokens = 0;do 	{	char sLine[SLEN];	fgets(sLine, SLEN, pFile);	char *comment = strchr(sLine,'#');	if (comment != NULL) 		*comment = 0;	char *token = NULL, *input = &sLine[0];	while (nTokens < 4 && (token = strtok(input," \t\n\r")) != NULL)		{		switch (nTokens)			{			case 0:				if (strcmp(token,"P5") != 0)					if (fExitOnErr)						Err("%s has a bad header (first two bytes are not \"P5\")", sPath);					else						return "bad header (first two bytes are not \"P5\")";				break;			case 1:				width = atoi(token);				break;			case 2:				height = atoi(token);				break;			case 3:				DataSize = atoi(token);				if (DataSize != 255)					if (fExitOnErr)						Err("This program can only deal with data sizes of 255 and "							"%s has a data size of %d", sPath, DataSize);					else						return "data size not 255";				break;			default:				break;			}		nTokens++;		input = NULL;		}	}while (nTokens < 4);if (width < 0 || width > CONF_nMaxImageDim || height > CONF_nMaxImageDim || height < 0)	if (fExitOnErr)		Err("%s has a strange width %d or height %d", sPath, width, height);	else		return "strange width or height";Image ImgTemp(width, height);Fread((char *)ImgTemp.buf , 1, width * height, pFile, sPath);fclose(pFile);if (pRgbImg)	{	pRgbImg->dim(width, height);	byte *pTo = (byte *)(pRgbImg->buf);	for (int iy = height-1; iy >= 0; iy--)		for (int ix = 0; ix < width; ix++)			{			byte b = ImgTemp(ix, iy);			*pTo++ = b;			*pTo++ = b;			*pTo++ = b;			}	}if (pImg)	*pImg = ImgTemp;return NULL;	// success}//-----------------------------------------------------------------------------char *sLoadPgm(Image &Img, 					 		// out			   const char *sPath, bool fExitOnErr)	// in{return sLoadPgm(&Img, NULL, sPath, fExitOnErr);}//-----------------------------------------------------------------------------// Load a .ppm file.  See the header of sLoadImage for some details.static char *sLoadPpm (Image *pImg, RgbImage *pRgbImg, const char *sPath, bool fExitOnErr){FILE *pFile = fopen(sPath, "rb");if (!pFile)	if (fExitOnErr)		Err("Can't open %s", sPath);	else		{		sprintf(sgErr, "Can't open %s", sPath);		return sgErr;		}int width=-1, height=-1, DataSize, nTokens = 0;do 	{	char sLine[SLEN];	fgets(sLine, SLEN, pFile);	char *comment = strchr(sLine,'#');	if (comment != NULL) 		*comment = 0;	char *token = NULL, *input = &sLine[0];	while (nTokens < 4 && (token = strtok(input," \t\n\r")) != NULL)		{		switch (nTokens)			{			case 0:				if (strcmp(token,"P6") != 0)					if (fExitOnErr)						Err("%s has a bad header (first two bytes are not \"P6\")", sPath);					else						return "bad header (first two bytes are not \"P6\")";				break;			case 1:				width = atoi(token);				break;			case 2:				height = atoi(token);				break;			case 3:				DataSize = atoi(token);				if (DataSize != 255)					if (fExitOnErr)						Err("This program can only deal with data sizes of 255\n"							"and %s has a data size of %d", sPath, DataSize);					else						return "data size not 255";				break;			default:				break;			}		nTokens++;		input = NULL;		}	}while (nTokens < 4);if (width < 0 || width > CONF_nMaxImageDim || height > CONF_nMaxImageDim || height < 0)	if (fExitOnErr)		Err("%s has a strange width %d or height", sPath, width, height);	else		return "strange width or height";RgbImage RgbTemp(width, height);Fread(RgbTemp.buf, 1, 3 * width * height, pFile, sPath);fclose(pFile);if (pImg)	{	// copy pRgbImg into buf, converting to gray	pImg->dim(width, height);	for (int iy = 0; iy < height; iy++)		for (int ix = 0; ix < width; ix++) 			{				// CIE conversion to gray, add 500 to take care of rounding			// Colors are reversed so have to take care of that too			tRGB c = RgbTemp(ix, iy);			(*pImg)(ix, iy) = byte((299 * c.Blue + 587 * c.Green + 114 * c.Red + 500) / 1000);			}	}if (pRgbImg)	{	// Image comes in upside down with colors reversed.  Fix that.	pRgbImg->dim(width, height);	for (int iy = 0, y1 = height-1; iy < height; iy++, y1--)		for (int ix = 0; ix < width; ix++)			{			(*pRgbImg)(ix, iy).Red = RgbTemp(ix, y1).Blue;			(*pRgbImg)(ix, iy).Green = RgbTemp(ix, y1).Green;			(*pRgbImg)(ix, iy).Blue = RgbTemp(ix, y1).Red;			}	}return NULL;	// success}//-----------------------------------------------------------------------------static FILE *pOpenTempFile (char sPath[], 									// out							const char sTemplate[], const char sMode[])		// in{char sTemplate1[SLEN];sprintf(sTemplate1, "%sXXXXXX", sTemplate);char *sFile = _mktemp(sTemplate1);if (!sFile)	SysErr("Can't generate temporary filename");char *sTmpDir = getenv("TMPDIR");if (!sTmpDir)	sTmpDir = getenv("TEMP");if (!sTmpDir)	sTmpDir = getenv("TMP");if (!sTmpDir)	SysErr("Can't find temporary directory (no environment variables TMPDIR TEMP TMP)");_makepath(sPath, "", sTmpDir, sFile, "tmp");return Fopen(sPath, sMode);		// will give err msg and exit if can't open the file}//-----------------------------------------------------------------------------// Load an image.  Knows about different types of files like BMPs and JPEGs//// This uses the file extension to determine file type.//// pImg is gray version of the image.      Caller must free it.  Set to NULL if you don't need it.// pRgbImg is color version of the image.  Caller must free it.  Set to NULL if you don't need it.//// sPath is the file name.// Set fVerbose if you want to tell the user that you are reading the file.//// fRemovePad=false only applies to RGB bitmaps and is needed to for StretchDIBits() under windowschar *sLoadImage (Image *pImg, RgbImage *pRgbImg, 										// out				  const char *sPath, bool fVerbose, bool fExitOnErr, bool fRemovePad)	// in{bprintf(!fVerbose, "Reading %s\n", sPath);if (sPath[0] == 0)	{	sprintf(sgErr, "Null path name, can't load image");	if (fExitOnErr)		Err(sgErr);	else		return sgErr;	}char sDrive[_MAX_DRIVE], sDir[_MAX_DIR], sFname[_MAX_FNAME], sExt[_MAX_EXT];_splitpath(sPath, sDrive, sDir, sFname, sExt);if (sExt[0] == 0)	{	sprintf(sgErr, "Filename %s has no extension: can't determine the image type to read from disk", sPath);	if (fExitOnErr)		Err(sgErr);	else		return sgErr;	}switch (toupper(sExt[1]))	{	case 'B':		return sLoadBmp(pImg, pRgbImg, sPath, fExitOnErr, fRemovePad);		break;	case 'J':		{		// file is a JPEG file: create a temporary BMP file and use that instead

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -