图片浏览器总结

1.框架

2.文件管理

工程目录结构

include头文件目录

3.各个模块解析

格式format模块(在render目录下)

Makefile

obj-y += picfmt_manager.o
obj-y += bmp.o
obj-y += jpg.o

picfmt_manager.h

#ifndef _PIC_MANAGER_H
#define _PIC_MANAGER_H

#include <config.h>
#include <pic_operation.h>
#include <page_manager.h>
#include <file.h>

/**********************************************************************
 * 函数名称: RegisterPicFileParser
 * 功能描述: 注册"图片文件解析模块", "图片文件解析模块"就是怎么从BMP/JPG等图片文件中解析出象素数据
 * 输入参数: ptPicFileParser - 一个结构体,内含"图片文件解析模块"的操作函数
 * 输出参数: 无
 * 返 回 值: 0 - 成功, 其他值 - 失败
 * 修改日期        版本号     修改人	      修改内容
 * -----------------------------------------------
 * 2013/02/08	     V1.0	  韦东山	      创建
 ***********************************************************************/
int RegisterPicFileParser(PT_PicFileParser ptPicFileParser);

/**********************************************************************
 * 函数名称: ShowPicFmts
 * 功能描述: 显示本程序能支持的"图片文件解析模块"
 * 输入参数: 无
 * 输出参数: 无
 * 返 回 值: 无
 * 修改日期        版本号     修改人	      修改内容
 * -----------------------------------------------
 * 2013/02/08	     V1.0	  韦东山	      创建
 ***********************************************************************/
void ShowPicFmts(void);

/**********************************************************************
 * 函数名称: PicFmtsInit
 * 功能描述: 调用各个"图片文件解析模块"的初始化函数,就是注册它们
 * 输入参数: 无
 * 输出参数: 无
 * 返 回 值: 0 - 成功, 其他值 - 失败
 * 修改日期        版本号     修改人	      修改内容
 * -----------------------------------------------
 * 2013/02/08	     V1.0	  韦东山	      创建
 ***********************************************************************/
int PicFmtsInit(void);

/**********************************************************************
 * 函数名称: JPGParserInit
 * 功能描述: 注册"JPG文件解析模块"
 * 输入参数: 无
 * 输出参数: 无
 * 返 回 值: 0 - 成功, 其他值 - 失败
 * 修改日期        版本号     修改人	      修改内容
 * -----------------------------------------------
 * 2013/02/08	     V1.0	  韦东山	      创建
 ***********************************************************************/
int JPGParserInit(void);

/**********************************************************************
 * 函数名称: BMPParserInit
 * 功能描述: 注册"BMP文件解析模块"
 * 输入参数: 无
 * 输出参数: 无
 * 返 回 值: 0 - 成功, 其他值 - 失败
 * 修改日期        版本号     修改人	      修改内容
 * -----------------------------------------------
 * 2013/02/08	     V1.0	  韦东山	      创建
 ***********************************************************************/
int BMPParserInit(void);

/**********************************************************************
 * 函数名称: Parser
 * 功能描述: 根据名字取出指定的"图片文件解析模块"
 * 输入参数: pcName - 名字
 * 输出参数: 无
 * 返 回 值: NULL   - 失败,没有指定的模块, 
 *            非NULL - "图片文件解析模块"的PT_PicFileParser结构体指针
 * 修改日期        版本号     修改人	      修改内容
 * -----------------------------------------------
 * 2013/02/08	     V1.0	  韦东山	      创建
 ***********************************************************************/
PT_PicFileParser Parser(char *pcName);

/**********************************************************************
 * 函数名称: GetParser
 * 功能描述: 找到能支持指定文件的"图片文件解析模块"
 * 输入参数: ptFileMap - 内含文件信息
 * 输出参数: 无
 * 返 回 值: NULL   - 失败,没有指定的模块, 
 *            非NULL - 支持该文件的"图片文件解析模块"的PT_PicFileParser结构体指针
 * 修改日期        版本号     修改人	      修改内容
 * -----------------------------------------------
 * 2013/02/08	     V1.0	  韦东山	      创建
 ***********************************************************************/
PT_PicFileParser GetParser(PT_FileMap ptFileMap);

#endif /* _PIC_MANAGER_H */

picfmt_manager.c

#include <config.h>
#include <pic_operation.h>
#include <picfmt_manager.h>
#include <string.h>


static PT_PicFileParser g_ptPicFileParserHead;

/**********************************************************************
 * 函数名称: RegisterPicFileParser
 * 功能描述: 注册"图片文件解析模块", "图片文件解析模块"就是怎么从BMP/JPG等图片文件中解析出象素数据
 * 输入参数: ptPicFileParser - 一个结构体,内含"图片文件解析模块"的操作函数
 * 输出参数: 无
 * 返 回 值: 0 - 成功, 其他值 - 失败
 * 修改日期        版本号     修改人	      修改内容
 * -----------------------------------------------
 * 2013/02/08	     V1.0	  韦东山	      创建
 ***********************************************************************/
int RegisterPicFileParser(PT_PicFileParser ptPicFileParser)
{
	PT_PicFileParser ptTmp;

	if (!g_ptPicFileParserHead)
	{
		g_ptPicFileParserHead   = ptPicFileParser;
		ptPicFileParser->ptNext = NULL;
	}
	else
	{
		ptTmp = g_ptPicFileParserHead;
		while (ptTmp->ptNext)
		{
			ptTmp = ptTmp->ptNext;
		}
		ptTmp->ptNext	  = ptPicFileParser;
		ptPicFileParser->ptNext = NULL;
	}

	return 0;
}


/**********************************************************************
 * 函数名称: ShowPicFmts
 * 功能描述: 显示本程序能支持的"图片文件解析模块"
 * 输入参数: 无
 * 输出参数: 无
 * 返 回 值: 无
 * 修改日期        版本号     修改人	      修改内容
 * -----------------------------------------------
 * 2013/02/08	     V1.0	  韦东山	      创建
 ***********************************************************************/
void ShowPicFmts(void)
{
	int i = 0;
	PT_PicFileParser ptTmp = g_ptPicFileParserHead;

	while (ptTmp)
	{
		printf("%02d %s
", i++, ptTmp->name);
		ptTmp = ptTmp->ptNext;
	}
}

/**********************************************************************
 * 函数名称: Parser
 * 功能描述: 根据名字取出指定的"图片文件解析模块"
 * 输入参数: pcName - 名字
 * 输出参数: 无
 * 返 回 值: NULL   - 失败,没有指定的模块, 
 *            非NULL - "图片文件解析模块"的PT_PicFileParser结构体指针
 * 修改日期        版本号     修改人	      修改内容
 * -----------------------------------------------
 * 2013/02/08	     V1.0	  韦东山	      创建
 ***********************************************************************/
PT_PicFileParser Parser(char *pcName)
{
	PT_PicFileParser ptTmp = g_ptPicFileParserHead;
	
	while (ptTmp)
	{
		if (strcmp(ptTmp->name, pcName) == 0)
		{
			return ptTmp;
		}
		ptTmp = ptTmp->ptNext;
	}
	return NULL;
}

/**********************************************************************
 * 函数名称: GetParser
 * 功能描述: 找到能支持指定文件的"图片文件解析模块"
 * 输入参数: ptFileMap - 内含文件信息
 * 输出参数: 无
 * 返 回 值: NULL   - 失败,没有指定的模块, 
 *            非NULL - 支持该文件的"图片文件解析模块"的PT_PicFileParser结构体指针
 * 修改日期        版本号     修改人	      修改内容
 * -----------------------------------------------
 * 2013/02/08	     V1.0	  韦东山	      创建
 ***********************************************************************/
PT_PicFileParser GetParser(PT_FileMap ptFileMap)
{
	PT_PicFileParser ptTmp = g_ptPicFileParserHead;
	
	while (ptTmp)
	{
		if (ptTmp->isSupport(ptFileMap))
		{
			return ptTmp;
		}
		ptTmp = ptTmp->ptNext;
	}
	return NULL;
}

/**********************************************************************
 * 函数名称: PicFmtsInit
 * 功能描述: 调用各个"图片文件解析模块"的初始化函数,就是注册它们
 * 输入参数: 无
 * 输出参数: 无
 * 返 回 值: 0 - 成功, 其他值 - 失败
 * 修改日期        版本号     修改人	      修改内容
 * -----------------------------------------------
 * 2013/02/08	     V1.0	  韦东山	      创建
 ***********************************************************************/
int PicFmtsInit(void)
{
	int iError;

	iError = BMPParserInit();
	iError |= JPGParserInit();
		
	return iError;
}

jpg.c

#include <config.h>
#include <pic_operation.h>
#include <picfmt_manager.h>
#include <file.h>
#include <stdlib.h>
#include <string.h>
#include <setjmp.h>
#include <jpeglib.h>

typedef struct MyErrorMgr
{
	struct jpeg_error_mgr pub;
	jmp_buf setjmp_buffer;
}T_MyErrorMgr, *PT_MyErrorMgr;

static int isJPGFormat(PT_FileMap ptFileMap);
static int GetPixelDatasFrmJPG(PT_FileMap ptFileMap, PT_PixelDatas ptPixelDatas);
static int FreePixelDatasForJPG(PT_PixelDatas ptPixelDatas);

static T_PicFileParser g_tJPGParser = {
	.name           = "jpg",
	.isSupport      = isJPGFormat,
	.GetPixelDatas  = GetPixelDatasFrmJPG,
	.FreePixelDatas = FreePixelDatasForJPG,	
};

/**********************************************************************
 * 函数名称: MyErrorExit
 * 功能描述: 自定义的libjpeg库出错处理函数
 *            默认的错误处理函数是让程序退出,我们当然不会使用它
 *            参考libjpeg里的bmp.c编写了这个错误处理函数
 * 输入参数: ptCInfo - libjpeg库抽象出来的通用结构体
 * 输出参数: 无
 * 返 回 值: 无
 * 修改日期        版本号     修改人	      修改内容
 * -----------------------------------------------
 * 2013/02/08	     V1.0	  韦东山	      创建
 ***********************************************************************/
static void MyErrorExit(j_common_ptr ptCInfo)
{
	static char errStr[JMSG_LENGTH_MAX];
	
	PT_MyErrorMgr ptMyErr = (PT_MyErrorMgr)ptCInfo->err;

	/* Create the message */
	(*ptCInfo->err->format_message) (ptCInfo, errStr);
	DBG_PRINTF("%s
", errStr);

	longjmp(ptMyErr->setjmp_buffer, 1);
}

/**********************************************************************
 * 函数名称: isJPGFormat
 * 功能描述: JPG模块是否支持该文件,即该文件是否为JPG文件
 * 输入参数: ptFileMap - 内含文件信息
 * 输出参数: 无
 * 返 回 值: 0 - 不支持, 1 - 支持
 * 修改日期        版本号     修改人	      修改内容
 * -----------------------------------------------
 * 2013/02/08	     V1.0	  韦东山	      创建
 ***********************************************************************/
static int isJPGFormat(PT_FileMap ptFileMap)
{
	struct jpeg_decompress_struct tDInfo;

	/* 默认的错误处理函数是让程序退出
	 * 我们参考libjpeg里的bmp.c编写自己的错误处理函数
	 */
	//struct jpeg_error_mgr tJErr;   
	T_MyErrorMgr tJerr;
	int iRet;

	fseek(ptFileMap->tFp, 0, SEEK_SET);

	// 分配和初始化一个decompression结构体
	// tDInfo.err = jpeg_std_error(&tJErr);
	tDInfo.err               = jpeg_std_error(&tJerr.pub);
	tJerr.pub.error_exit     = MyErrorExit;

	if(setjmp(tJerr.setjmp_buffer))
	{
		/* 如果程序能运行到这里, 表示JPEG解码出错 */
		jpeg_destroy_decompress(&tDInfo);
		return 0;;
	}
	
	jpeg_create_decompress(&tDInfo);

	// 用jpeg_read_header获得jpg信息
	jpeg_stdio_src(&tDInfo, ptFileMap->tFp);

	iRet = jpeg_read_header(&tDInfo, TRUE);
	jpeg_abort_decompress(&tDInfo);

	return (iRet == JPEG_HEADER_OK);
}

/**********************************************************************
 * 函数名称: CovertOneLine
 * 功能描述: 把已经从JPG文件取出的一行象素数据,转换为能在显示设备上使用的格式
 * 输入参数: iWidth      - 宽度,即多少个象素
 *            iSrcBpp     - 已经从JPG文件取出的一行象素数据里面,一个象素用多少位来表示
 *            iDstBpp     - 显示设备上一个象素用多少位来表示
 *            pudSrcDatas - 已经从JPG文件取出的一行象素数所存储的位置
 *            pudDstDatas - 转换所得数据存储的位置
 * 输出参数: 无
 * 返 回 值: 0 - 成功, 其他值 - 失败
 * 修改日期        版本号     修改人	      修改内容
 * -----------------------------------------------
 * 2013/02/08	     V1.0	  韦东山	      创建
 ***********************************************************************/
static int CovertOneLine(int iWidth, int iSrcBpp, int iDstBpp, unsigned char *pudSrcDatas, unsigned char *pudDstDatas)
{
	unsigned int dwRed;
	unsigned int dwGreen;
	unsigned int dwBlue;
	unsigned int dwColor;

	unsigned short *pwDstDatas16bpp = (unsigned short *)pudDstDatas;
	unsigned int   *pwDstDatas32bpp = (unsigned int *)pudDstDatas;

	int i;
	int pos = 0;

	if (iSrcBpp != 24)
	{
		return -1;
	}

	if (iDstBpp == 24)
	{
		memcpy(pudDstDatas, pudSrcDatas, iWidth*3);
	}
	else
	{
		for (i = 0; i < iWidth; i++)
		{
			dwRed   = pudSrcDatas[pos++];
			dwGreen = pudSrcDatas[pos++];
			dwBlue  = pudSrcDatas[pos++];
			if (iDstBpp == 32)
			{
				dwColor = (dwRed << 16) | (dwGreen << 8) | dwBlue;
				*pwDstDatas32bpp = dwColor;
				pwDstDatas32bpp++;
			}
			else if (iDstBpp == 16)
			{
				/* 565 */
				dwRed   = dwRed >> 3;
				dwGreen = dwGreen >> 2;
				dwBlue  = dwBlue >> 3;
				dwColor = (dwRed << 11) | (dwGreen << 5) | (dwBlue);
				*pwDstDatas16bpp = dwColor;
				pwDstDatas16bpp++;
			}
		}
	}
	return 0;
}


/**********************************************************************
 * 函数名称: GetPixelDatasFrmJPG
 * 功能描述: 把JPG文件中的图像数据,取出并转换为能在显示设备上使用的格式
 * 输入参数: ptFileMap    - 内含文件信息
 * 输出参数: ptPixelDatas - 内含象素数据
 *            ptPixelDatas->iBpp 是输入的参数, 它确定从JPG文件得到的数据要转换为该BPP
 * 返 回 值: 0 - 成功, 其他值 - 失败
 * 修改日期        版本号     修改人          修改内容
 * -----------------------------------------------
 * 2013/02/08        V1.0     韦东山          创建
 ***********************************************************************/
static int GetPixelDatasFrmJPG(PT_FileMap ptFileMap, PT_PixelDatas ptPixelDatas)
{
	struct jpeg_decompress_struct tDInfo;
	//struct jpeg_error_mgr tJErr;
	int iRet;
	int iRowStride;
	unsigned char *aucLineBuffer = NULL;
	unsigned char *pucDest;
	T_MyErrorMgr tJerr;

	fseek(ptFileMap->tFp, 0, SEEK_SET);

	// 分配和初始化一个decompression结构体
	//tDInfo.err = jpeg_std_error(&tJErr);

	tDInfo.err               = jpeg_std_error(&tJerr.pub);
	tJerr.pub.error_exit     = MyErrorExit;

	if(setjmp(tJerr.setjmp_buffer))
	{
		/* 如果程序能运行到这里, 表示JPEG解码出错 */
		jpeg_destroy_decompress(&tDInfo);
		if (aucLineBuffer)
		{
			free(aucLineBuffer);
		}
		if (ptPixelDatas->aucPixelDatas)
		{
			free(ptPixelDatas->aucPixelDatas);
		}
		return -1;
	}

	jpeg_create_decompress(&tDInfo);

	// 用jpeg_read_header获得jpg信息
	jpeg_stdio_src(&tDInfo, ptFileMap->tFp);

	iRet = jpeg_read_header(&tDInfo, TRUE);

	// 设置解压参数,比如放大、缩小
	tDInfo.scale_num = tDInfo.scale_denom = 1;
	
	// 启动解压:jpeg_start_decompress	
	jpeg_start_decompress(&tDInfo);
	
	// 一行的数据长度
	iRowStride = tDInfo.output_width * tDInfo.output_components;
	aucLineBuffer = malloc(iRowStride);

	if (NULL == aucLineBuffer)
	{
		return -1;
	}

	ptPixelDatas->iWidth  = tDInfo.output_width;
	ptPixelDatas->iHeight = tDInfo.output_height;
	//ptPixelDatas->iBpp    = iBpp;
	ptPixelDatas->iLineBytes    = ptPixelDatas->iWidth * ptPixelDatas->iBpp / 8;
	ptPixelDatas->iTotalBytes   = ptPixelDatas->iHeight * ptPixelDatas->iLineBytes;
	ptPixelDatas->aucPixelDatas = malloc(ptPixelDatas->iTotalBytes);
	if (NULL == ptPixelDatas->aucPixelDatas)
	{
		return -1;
	}

	pucDest = ptPixelDatas->aucPixelDatas;

	// 循环调用jpeg_read_scanlines来一行一行地获得解压的数据
	while (tDInfo.output_scanline < tDInfo.output_height) 
	{
		/* 得到一行数据,里面的颜色格式为0xRR, 0xGG, 0xBB */
		(void) jpeg_read_scanlines(&tDInfo, &aucLineBuffer, 1);

		// 转到ptPixelDatas去
		CovertOneLine(ptPixelDatas->iWidth, 24, ptPixelDatas->iBpp, aucLineBuffer, pucDest);
		pucDest += ptPixelDatas->iLineBytes;
	}
	
	free(aucLineBuffer);
	jpeg_finish_decompress(&tDInfo);
	jpeg_destroy_decompress(&tDInfo);

	return 0;
}

/**********************************************************************
 * 函数名称: FreePixelDatasForJPG
 * 功能描述: GetPixelDatasFrmJPG的反函数,把象素数据所占内存释放掉
 * 输入参数: ptPixelDatas - 内含象素数据
 * 输出参数: 无
 * 返 回 值: 0 - 成功, 其他值 - 失败
 * 修改日期        版本号     修改人          修改内容
 * -----------------------------------------------
 * 2013/02/08        V1.0     韦东山          创建
 ***********************************************************************/
static int FreePixelDatasForJPG(PT_PixelDatas ptPixelDatas)
{
	free(ptPixelDatas->aucPixelDatas);
	return 0;
}

/**********************************************************************
 * 函数名称: JPGParserInit
 * 功能描述: 注册"JPG文件解析模块"
 * 输入参数: 无
 * 输出参数: 无
 * 返 回 值: 0 - 成功, 其他值 - 失败
 * 修改日期        版本号     修改人	      修改内容
 * -----------------------------------------------
 * 2013/02/08	     V1.0	  韦东山	      创建
 ***********************************************************************/
int JPGParserInit(void)
{
	return RegisterPicFileParser(&g_tJPGParser);
}

bmp.c

#include <config.h>
#include <pic_operation.h>
#include <picfmt_manager.h>
#include <file.h>
#include <stdlib.h>
#include <string.h>

#pragma pack(push) /* 将当前pack设置压栈保存 */
#pragma pack(1)    /* 必须在结构体定义之前使用,这是为了让结构体中各成员按1字节对齐 */

typedef struct tagBITMAPFILEHEADER { /* bmfh */
	unsigned short bfType; 
	unsigned long  bfSize;
	unsigned short bfReserved1;
	unsigned short bfReserved2;
	unsigned long  bfOffBits;
} BITMAPFILEHEADER;

typedef struct tagBITMAPINFOHEADER { /* bmih */
	unsigned long  biSize;
	unsigned long  biWidth;
	unsigned long  biHeight;
	unsigned short biPlanes;
	unsigned short biBitCount;
	unsigned long  biCompression;
	unsigned long  biSizeImage;
	unsigned long  biXPelsPerMeter;
	unsigned long  biYPelsPerMeter;
	unsigned long  biClrUsed;
	unsigned long  biClrImportant;
} BITMAPINFOHEADER;

#pragma pack(pop) /* 恢复先前的pack设置 */

static int isBMPFormat(PT_FileMap ptFileMap);
static int GetPixelDatasFrmBMP(PT_FileMap ptFileMap, PT_PixelDatas ptPixelDatas);
static int FreePixelDatasForBMP(PT_PixelDatas ptPixelDatas);

static T_PicFileParser g_tBMPParser = {
	.name           = "bmp",
	.isSupport      = isBMPFormat,
	.GetPixelDatas  = GetPixelDatasFrmBMP,
	.FreePixelDatas = FreePixelDatasForBMP,	
};

/**********************************************************************
 * 函数名称: isBMPFormat
 * 功能描述: BMP模块是否支持该文件,即该文件是否为BMP文件
 * 输入参数: ptFileMap - 内含文件信息
 * 输出参数: 无
 * 返 回 值: 0 - 不支持, 1 - 支持
 * 修改日期        版本号     修改人	      修改内容
 * -----------------------------------------------
 * 2013/02/08	     V1.0	  韦东山	      创建
 ***********************************************************************/
static int isBMPFormat(PT_FileMap ptFileMap)
{
	unsigned char *aFileHead = ptFileMap->pucFileMapMem;
	
	if (aFileHead[0] != 0x42 || aFileHead[1] != 0x4d)
		return 0;
	else
		return 1;
}

/**********************************************************************
 * 函数名称: CovertOneLine
 * 功能描述: 把BMP文件中一行的象素数据,转换为能在显示设备上使用的格式
 * 输入参数: iWidth      - 宽度,即多少个象素
 *            iSrcBpp     - BMP文件中一个象素用多少位来表示
 *            iDstBpp     - 显示设备上一个象素用多少位来表示
 *            pudSrcDatas - BMP文件里该行数据的位置
 *            pudDstDatas - 转换所得数据存储的位置
 * 输出参数: 无
 * 返 回 值: 0 - 成功, 其他值 - 失败
 * 修改日期        版本号     修改人	      修改内容
 * -----------------------------------------------
 * 2013/02/08	     V1.0	  韦东山	      创建
 ***********************************************************************/
static int CovertOneLine(int iWidth, int iSrcBpp, int iDstBpp, unsigned char *pudSrcDatas, unsigned char *pudDstDatas)
{
	unsigned int dwRed;
	unsigned int dwGreen;
	unsigned int dwBlue;
	unsigned int dwColor;

	unsigned short *pwDstDatas16bpp = (unsigned short *)pudDstDatas;
	unsigned int   *pwDstDatas32bpp = (unsigned int *)pudDstDatas;

	int i;
	int pos = 0;

	if (iSrcBpp != 24)
	{
		return -1;
	}

	if (iDstBpp == 24)
	{
		memcpy(pudDstDatas, pudSrcDatas, iWidth*3);
	}
	else
	{
		for (i = 0; i < iWidth; i++)
		{
			dwBlue  = pudSrcDatas[pos++];
			dwGreen = pudSrcDatas[pos++];
			dwRed   = pudSrcDatas[pos++];
			if (iDstBpp == 32)
			{
				dwColor = (dwRed << 16) | (dwGreen << 8) | dwBlue;
				*pwDstDatas32bpp = dwColor;
				pwDstDatas32bpp++;
			}
			else if (iDstBpp == 16)
			{
				/* 565 */
				dwRed   = dwRed >> 3;
				dwGreen = dwGreen >> 2;
				dwBlue  = dwBlue >> 3;
				dwColor = (dwRed << 11) | (dwGreen << 5) | (dwBlue);
				*pwDstDatas16bpp = dwColor;
				pwDstDatas16bpp++;
			}
		}
	}
	return 0;
}

/**********************************************************************
 * 函数名称: GetPixelDatasFrmBMP
 * 功能描述: 把BMP文件中的象素数据,取出并转换为能在显示设备上使用的格式
 * 输入参数: ptFileMap    - 内含文件信息
 * 输出参数: ptPixelDatas - 内含象素数据
 *            ptPixelDatas->iBpp 是输入的参数, 它确定从BMP文件得到的数据要转换为该BPP
 * 返 回 值: 0 - 成功, 其他值 - 失败
 * 修改日期        版本号     修改人          修改内容
 * -----------------------------------------------
 * 2013/02/08        V1.0     韦东山          创建
 ***********************************************************************/
static int GetPixelDatasFrmBMP(PT_FileMap ptFileMap, PT_PixelDatas ptPixelDatas)
{
	BITMAPFILEHEADER *ptBITMAPFILEHEADER;
	BITMAPINFOHEADER *ptBITMAPINFOHEADER;

	unsigned char *aFileHead;

	int iWidth;
	int iHeight;
	int iBMPBpp;
	int y;

	unsigned char *pucSrc;
	unsigned char *pucDest;
	int iLineWidthAlign;
	int iLineWidthReal;

	aFileHead = ptFileMap->pucFileMapMem;

	ptBITMAPFILEHEADER = (BITMAPFILEHEADER *)aFileHead;
	ptBITMAPINFOHEADER = (BITMAPINFOHEADER *)(aFileHead + sizeof(BITMAPFILEHEADER));

	iWidth = ptBITMAPINFOHEADER->biWidth;
	iHeight = ptBITMAPINFOHEADER->biHeight;
	iBMPBpp = ptBITMAPINFOHEADER->biBitCount;

	if (iBMPBpp != 24)
	{
		DBG_PRINTF("iBMPBpp = %d
", iBMPBpp);
		DBG_PRINTF("sizeof(BITMAPFILEHEADER) = %d
", sizeof(BITMAPFILEHEADER));
		return -1;
	}

	ptPixelDatas->iWidth  = iWidth;
	ptPixelDatas->iHeight = iHeight;
	//ptPixelDatas->iBpp    = iBpp;
	ptPixelDatas->iLineBytes    = iWidth * ptPixelDatas->iBpp / 8;
	ptPixelDatas->iTotalBytes   = ptPixelDatas->iHeight * ptPixelDatas->iLineBytes;
	ptPixelDatas->aucPixelDatas = malloc(ptPixelDatas->iTotalBytes);
	if (NULL == ptPixelDatas->aucPixelDatas)
	{
		return -1;
	}

	iLineWidthReal = iWidth * iBMPBpp / 8;
	iLineWidthAlign = (iLineWidthReal + 3) & ~0x3;   /* 向4取整 */
		
	pucSrc = aFileHead + ptBITMAPFILEHEADER->bfOffBits;
	pucSrc = pucSrc + (iHeight - 1) * iLineWidthAlign;

	pucDest = ptPixelDatas->aucPixelDatas;
	
	for (y = 0; y < iHeight; y++)
	{		
		//memcpy(pucDest, pucSrc, iLineWidthReal);
		CovertOneLine(iWidth, iBMPBpp, ptPixelDatas->iBpp, pucSrc, pucDest);
		pucSrc  -= iLineWidthAlign;
		pucDest += ptPixelDatas->iLineBytes;
	}
	return 0;	
}

/**********************************************************************
 * 函数名称: FreePixelDatasForBMP
 * 功能描述: GetPixelDatasFrmBMP的反函数,把象素数据所占内存释放掉
 * 输入参数: ptPixelDatas - 内含象素数据
 * 输出参数: 无
 * 返 回 值: 0 - 成功, 其他值 - 失败
 * 修改日期        版本号     修改人          修改内容
 * -----------------------------------------------
 * 2013/02/08        V1.0     韦东山          创建
 ***********************************************************************/
static int FreePixelDatasForBMP(PT_PixelDatas ptPixelDatas)
{
	free(ptPixelDatas->aucPixelDatas);
	return 0;
}

/**********************************************************************
 * 函数名称: BMPParserInit
 * 功能描述: 注册"BMP文件解析模块"
 * 输入参数: 无
 * 输出参数: 无
 * 返 回 值: 0 - 成功, 其他值 - 失败
 * 修改日期        版本号     修改人	      修改内容
 * -----------------------------------------------
 * 2013/02/08	     V1.0	  韦东山	      创建
 ***********************************************************************/
int BMPParserInit(void)
{
	return RegisterPicFileParser(&g_tBMPParser);
}

操作operation目录(在render目录下)

Makefile

obj-y += zoom.o
obj-y += merge.o

zoom.c

#include <config.h>
#include <pic_operation.h>
#include <stdlib.h>
#include <string.h>


/**********************************************************************
 * 函数名称: PicZoom
 * 功能描述: 近邻取样插值方法缩放图片
 *            注意该函数会分配内存来存放缩放后的图片,用完后要用free函数释放掉
 *            "近邻取样插值"的原理请参考网友"lantianyu520"所著的"图像缩放算法"
 * 输入参数: ptOriginPic - 内含原始图片的象素数据
 *            ptBigPic    - 内含缩放后的图片的象素数据
 * 输出参数: 无
 * 返 回 值: 0 - 成功, 其他值 - 失败
 * 修改日期        版本号     修改人	      修改内容
 * -----------------------------------------------
 * 2013/02/08	     V1.0	  韦东山	      创建
 ***********************************************************************/
int PicZoom(PT_PixelDatas ptOriginPic, PT_PixelDatas ptZoomPic)
{
    unsigned long dwDstWidth = ptZoomPic->iWidth;
    unsigned long* pdwSrcXTable;
    unsigned long x;
    unsigned long y;
    unsigned long dwSrcY;
    unsigned char *pucDest;
    unsigned char *pucSrc;
    unsigned long dwPixelBytes = ptOriginPic->iBpp/8;

    if (ptOriginPic->iBpp != ptZoomPic->iBpp)
    {
        return -1;
    }

    pdwSrcXTable = malloc(sizeof(unsigned long) * dwDstWidth);
    if (NULL == pdwSrcXTable)
    {
        DBG_PRINTF("malloc error!
");
        return -1;
    }

    for (x = 0; x < dwDstWidth; x++)//生成表 pdwSrcXTable
    {
        pdwSrcXTable[x]=(x*ptOriginPic->iWidth/ptZoomPic->iWidth);
    }

    for (y = 0; y < ptZoomPic->iHeight; y++)
    {			
        dwSrcY = (y * ptOriginPic->iHeight / ptZoomPic->iHeight);

        pucDest = ptZoomPic->aucPixelDatas + y*ptZoomPic->iLineBytes;
        pucSrc  = ptOriginPic->aucPixelDatas + dwSrcY*ptOriginPic->iLineBytes;
        
        for (x = 0; x <dwDstWidth; x++)
        {
            /* 原图座标: pdwSrcXTable[x],srcy
            * 缩放座标: x, y
            */
            memcpy(pucDest+x*dwPixelBytes, pucSrc+pdwSrcXTable[x]*dwPixelBytes, dwPixelBytes);
        }
    }

    free(pdwSrcXTable);
    return 0;
}

merge.c

#include <pic_operation.h>
#include <string.h>

/**********************************************************************
 * 函数名称: PicMerge
 * 功能描述: 把小图片合并入大图片里
 * 输入参数: iX,iY      - 小图片合并入大图片的某个区域, iX/iY确定这个区域的左上角座标
 *            ptSmallPic - 内含小图片的象素数据
 *            ptBigPic   - 内含大图片的象素数据
 * 输出参数: 无
 * 返 回 值: 0 - 成功, 其他值 - 失败
 * 修改日期        版本号     修改人	      修改内容
 * -----------------------------------------------
 * 2013/02/08	     V1.0	  韦东山	      创建
 ***********************************************************************/
int PicMerge(int iX, int iY, PT_PixelDatas ptSmallPic, PT_PixelDatas ptBigPic)
{
	int i;
	unsigned char *pucSrc;
	unsigned char *pucDst;
	
	if ((ptSmallPic->iWidth > ptBigPic->iWidth)  ||
		(ptSmallPic->iHeight > ptBigPic->iHeight) ||
		(ptSmallPic->iBpp != ptBigPic->iBpp))
	{
		return -1;
	}

	pucSrc = ptSmallPic->aucPixelDatas;
	pucDst = ptBigPic->aucPixelDatas + iY * ptBigPic->iLineBytes + iX * ptBigPic->iBpp / 8;
	for (i = 0; i < ptSmallPic->iHeight; i++)
	{
		memcpy(pucDst, pucSrc, ptSmallPic->iLineBytes);
		pucSrc += ptSmallPic->iLineBytes;
		pucDst += ptBigPic->iLineBytes;
	}
	return 0;
}


/**********************************************************************
 * 函数名称: PicMergeRegion
 * 功能描述: 把新图片的某部分, 合并入老图片的指定区域
 * 输入参数: iStartXofNewPic, iStartYofNewPic : 从新图片的(iStartXofNewPic, iStartYofNewPic)座标处开始读出数据用于合并
 *            iStartXofOldPic, iStartYofOldPic : 合并到老图片的(iStartXofOldPic, iStartYofOldPic)座标去
 *            iWidth, iHeight                  : 合并区域的大小
 *            ptNewPic                         : 新图片
 *            ptOldPic                         : 老图片
 * 输出参数: 无
 * 返 回 值: 0 - 成功, 其他值 - 失败
 * 修改日期        版本号     修改人          修改内容
 * -----------------------------------------------
 * 2013/02/08        V1.0     韦东山          创建
 ***********************************************************************/
int PicMergeRegion(int iStartXofNewPic, int iStartYofNewPic, int iStartXofOldPic, int iStartYofOldPic, int iWidth, int iHeight, PT_PixelDatas ptNewPic, PT_PixelDatas ptOldPic)
{
	int i;
	unsigned char *pucSrc;
	unsigned char *pucDst;
	int iLineBytesCpy = iWidth * ptNewPic->iBpp / 8;

	if ((iStartXofNewPic < 0 || iStartXofNewPic >= ptNewPic->iWidth) || 
		(iStartYofNewPic < 0 || iStartYofNewPic >= ptNewPic->iHeight) || 
		(iStartXofOldPic < 0 || iStartXofOldPic >= ptOldPic->iWidth) || 
		(iStartYofOldPic < 0 || iStartYofOldPic >= ptOldPic->iHeight))
	{
		return -1;
	}
	
	pucSrc = ptNewPic->aucPixelDatas + iStartYofNewPic * ptNewPic->iLineBytes + iStartXofNewPic * ptNewPic->iBpp / 8;
	pucDst = ptOldPic->aucPixelDatas + iStartYofOldPic * ptOldPic->iLineBytes + iStartXofOldPic * ptOldPic->iBpp / 8;
	for (i = 0; i < iHeight; i++)
	{
		memcpy(pucDst, pucSrc, iLineBytesCpy);
		pucSrc += ptNewPic->iLineBytes;
		pucDst += ptOldPic->iLineBytes;
	}
	return 0;
}

render模块(包含format,operation)

Makefile

obj-y += format/
obj-y += operation/
obj-y += render.o

picoperation.h

#ifndef _PIC_OPERATION_H
#define _PIC_OPERATION_H

#include <file.h>

/* 图片的象素数据 */
typedef struct PixelDatas {
	int iWidth;   /* 宽度: 一行有多少个象素 */
	int iHeight;  /* 高度: 一列有多少个象素 */
	int iBpp;     /* 一个象素用多少位来表示 */
	int iLineBytes;  /* 一行数据有多少字节 */
	int iTotalBytes; /* 所有字节数 */ 
	unsigned char *aucPixelDatas;  /* 象素数据存储的地方 */
}T_PixelDatas, *PT_PixelDatas;


typedef struct PicFileParser {
	char *name;                     /* 图片文件解析模块的名字 */
	int (*isSupport)(PT_FileMap ptFileMap);  /* 是否支持某文件 */
	int (*GetPixelDatas)(PT_FileMap ptFileMap, PT_PixelDatas ptPixelDatas);  /* 从文件中解析出图像的象素数据 */
	int (*FreePixelDatas)(PT_PixelDatas ptPixelDatas);  /* 释放图像的象素数据所占内存 */
	struct PicFileParser *ptNext;  /* 链表 */
}T_PicFileParser, *PT_PicFileParser;

#endif /* _PIC_OPERATION_H */

render.h

#ifndef _RENDER_H
#define _RENDER_H

#include <pic_operation.h>
#include <disp_manager.h>
#include <page_manager.h>

/**********************************************************************
 * 函数名称: PicZoom
 * 功能描述: 近邻取样插值方法缩放图片
 *            注意该函数会分配内存来存放缩放后的图片,用完后要用free函数释放掉
 *            "近邻取样插值"的原理请参考网友"lantianyu520"所著的"图像缩放算法"
 * 输入参数: ptOriginPic - 内含原始图片的象素数据
 *            ptBigPic    - 内含缩放后的图片的象素数据
 * 输出参数: 无
 * 返 回 值: 0 - 成功, 其他值 - 失败
 * 修改日期        版本号     修改人	      修改内容
 * -----------------------------------------------
 * 2013/02/08	     V1.0	  韦东山	      创建
 ***********************************************************************/
int PicZoom(PT_PixelDatas ptOriginPic, PT_PixelDatas ptZoomPic);

/**********************************************************************
 * 函数名称: PicMerge
 * 功能描述: 把小图片合并入大图片里
 * 输入参数: iX,iY      - 小图片合并入大图片的某个区域, iX/iY确定这个区域的左上角座标
 *            ptSmallPic - 内含小图片的象素数据
 *            ptBigPic   - 内含大图片的象素数据
 * 输出参数: 无
 * 返 回 值: 0 - 成功, 其他值 - 失败
 * 修改日期        版本号     修改人	      修改内容
 * -----------------------------------------------
 * 2013/02/08	     V1.0	  韦东山	      创建
 ***********************************************************************/
int PicMerge(int iX, int iY, PT_PixelDatas ptSmallPic, PT_PixelDatas ptBigPic);

/**********************************************************************
 * 函数名称: PicMergeRegion
 * 功能描述: 把新图片的某部分, 合并入老图片的指定区域
 * 输入参数: iStartXofNewPic, iStartYofNewPic : 从新图片的(iStartXofNewPic, iStartYofNewPic)座标处开始读出数据用于合并
 *            iStartXofOldPic, iStartYofOldPic : 合并到老图片的(iStartXofOldPic, iStartYofOldPic)座标去
 *            iWidth, iHeight                  : 合并区域的大小
 *            ptNewPic                         : 新图片
 *            ptOldPic                         : 老图片
 * 输出参数: 无
 * 返 回 值: 0 - 成功, 其他值 - 失败
 * 修改日期        版本号     修改人          修改内容
 * -----------------------------------------------
 * 2013/02/08        V1.0     韦东山          创建
 ***********************************************************************/
int PicMergeRegion(int iStartXofNewPic, int iStartYofNewPic, int iStartXofOldPic, int iStartYofOldPic, int iWidth, int iHeight, PT_PixelDatas ptNewPic, PT_PixelDatas ptOldPic);

/**********************************************************************
 * 函数名称: FlushVideoMemToDev
 * 功能描述: 把缓冲区中的数据刷到显示设备上去,即在显示设备上显示缓冲区中的图像
 * 输入参数: ptVideoMem - 缓冲区,内含象素数据
 * 输出参数: 无
 * 返 回 值: 0 - 成功, 其他值 - 失败
 * 修改日期        版本号     修改人	      修改内容
 * -----------------------------------------------
 * 2013/02/08	     V1.0	  韦东山	      创建
 ***********************************************************************/
void FlushVideoMemToDev(PT_VideoMem ptVideoMem);

/**********************************************************************
 * 函数名称: GetPixelDatasForIcon
 * 功能描述: 取出BMP格式的图标文件中的象素数据
 * 输入参数: strFileName  - BMP格式的图标文件名,它位于/etc/digitpic/icons目录下
 * 输出参数: ptPixelDatas - 内含象素数据,它所占的空间是通过malloc分配的,
 *                           不用时需要用FreePixelDatasForIcon来释放
 * 返 回 值: 0 - 成功, 其他值 - 失败
 * 修改日期        版本号     修改人	      修改内容
 * -----------------------------------------------
 * 2013/02/08	     V1.0	  韦东山	      创建
 ***********************************************************************/
int GetPixelDatasForIcon(char *strFileName, PT_PixelDatas ptPixelDatas);

/**********************************************************************
 * 函数名称: FreePixelDatasForIcon
 * 功能描述: 释放图像数据所占缓冲区
 * 输入参数: ptPixelDatas - 内含象素数据,它所占的空间是通过malloc分配的
 * 输出参数: 无
 * 返 回 值: 0 - 成功, 其他值 - 失败
 * 修改日期        版本号     修改人	      修改内容
 * -----------------------------------------------
 * 2013/02/08	     V1.0	  韦东山	      创建
 ***********************************************************************/
void FreePixelDatasForIcon(PT_PixelDatas ptPixelDatas);

/**********************************************************************
 * 函数名称: GetPixelDatasFrmFile
 * 功能描述: 从图片文件中取出象素数据
 * 输入参数: strFileName - 文件名,含绝对路径
 * 输出参数: ptPixelDatas - 内含象素数据
 * 返 回 值: 0 - 成功, 其他值 - 失败
 * 修改日期        版本号     修改人	      修改内容
 * -----------------------------------------------
 * 2013/02/08	     V1.0	  韦东山	      创建
 ***********************************************************************/
int GetPixelDatasFrmFile(char *strFileName, PT_PixelDatas ptPixelDatas);

/**********************************************************************
 * 函数名称: FreePixelDatasFrmFile
 * 功能描述: GetPixelDatasFrmFile从图片文件中取出象素数据时是动态分配内存的,
 *            FreePixelDatasFrmFile把分配的内存释放掉
 * 输入参数: ptPixelDatas - 内含象素数据
 * 输出参数: 无
 * 返 回 值: 无
 * 修改日期        版本号     修改人	      修改内容
 * -----------------------------------------------
 * 2013/02/08	     V1.0	  韦东山	      创建
 ***********************************************************************/
void FreePixelDatasFrmFile(PT_PixelDatas ptPixelDatas);

/**********************************************************************
 * 函数名称: ReleaseButton
 * 功能描述: 松开图标,只是改变显示设备上的图标按钮颜色
 * 输入参数: ptLayout   - 图标所在矩形区域
 * 输出参数: 无
 * 返 回 值: 无
 * 修改日期        版本号     修改人          修改内容
 * -----------------------------------------------
 * 2013/02/08        V1.0     韦东山          创建
 ***********************************************************************/
void ReleaseButton(PT_Layout ptLayout);

/**********************************************************************
 * 函数名称: PressButton
 * 功能描述: 按下图标,只是改变显示设备上的图标按钮颜色
 * 输入参数: ptLayout   - 图标所在矩形区域
 * 输出参数: 无
 * 返 回 值: 无
 * 修改日期        版本号     修改人          修改内容
 * -----------------------------------------------
 * 2013/02/08        V1.0     韦东山          创建
 ***********************************************************************/
void PressButton(PT_Layout ptLayout);

/**********************************************************************
 * 函数名称: MergerStringToCenterOfRectangleInVideoMem
 * 功能描述: 在VideoMem的指定矩形居中显示字符串
 *            参考: 03.freetype2th_arm6th_show_lines_center
 * 输入参数: iTopLeftX,iTopLeftY   - 矩形区域的左上角座标
 *            iBotRightX,iBotRightY - 矩形区域的右下角座标
 *            pucTextString         - 要显示的字符串
 *            ptVideoMem            - VideoMem
 * 输出参数: 无
 * 返 回 值: 0 - 成功,  其他值 - 失败
 * 修改日期        版本号     修改人          修改内容
 * -----------------------------------------------
 * 2013/02/08        V1.0     韦东山          创建
 ***********************************************************************/
int MergerStringToCenterOfRectangleInVideoMem(int iTopLeftX, int iTopLeftY, int iBotRightX, int iBotRightY, unsigned char *pucTextString, PT_VideoMem ptVideoMem);

/**********************************************************************
 * 函数名称: ClearRectangleInVideoMem
 * 功能描述: 清除VideoMem中某个矩形区域,设为某颜色
 * 输入参数: iTopLeftX,iTopLeftY   - 矩形区域的左上角座标
 *            iBotRightX,iBotRightY - 矩形区域的右下角座标
 *            ptVideoMem            - 设置VideoMem中的矩形区域
 *            dwColor               - 设置为这个颜色,颜色格式为0x00RRGGBB
 * 输出参数: 无
 * 返 回 值: 无
 * 修改日期        版本号     修改人	      修改内容
 * -----------------------------------------------
 * 2013/02/08	     V1.0	  韦东山	      创建
 ***********************************************************************/
void ClearRectangleInVideoMem(int iTopLeftX, int iTopLeftY, int iBotRightX, int iBotRightY, PT_VideoMem ptVideoMem, unsigned int dwColor);

/**********************************************************************
 * 函数名称: isPictureFileSupported
 * 功能描述: 判断本程序能否支持该图片文件,目前只能支持BMP/JPG格式的文件
 * 输入参数: strFileName - 文件名,含绝对路径
 * 输出参数: 无
 * 返 回 值: 0 - 不支持, 1 - 支持
 * 修改日期        版本号     修改人	      修改内容
 * -----------------------------------------------
 * 2013/02/08	     V1.0	  韦东山	      创建
 ***********************************************************************/
int isPictureFileSupported(char *strFileName);


#endif /* _RENDER_H */

render.c

https://gitee.com/super_glob/project_1_ebook/blob/master/render.c

page模块(page目录)

Makefile

obj-y += page_manager.o
obj-y += main_page.o
obj-y += setting_page.o
obj-y += interval_page.o
obj-y += browse_page.o
obj-y += auto_page.o
obj-y += manual_page.o

page_manager.h

#ifndef _PAGE_MANAGER_H
#define _PAGE_MANAGER_H

#include <input_manager.h>
#include <disp_manager.h>

typedef struct PageParams {
	int iPageID;                  /* 页面的ID */
	char strCurPictureFile[256];  /* 要处理的第1个图片文件 */
}T_PageParams, *PT_PageParams;

typedef struct PageLayout {
	int iTopLeftX;        /* 这个区域的左上角、右下角坐标 */
	int iTopLeftY;
	int iBotRightX;
	int iBotRightY;
	int iBpp;             /* 一个象素用多少位来表示 */
	int iMaxTotalBytes;
	PT_Layout atLayout;  /* 数组: 这个区域分成好几个小区域 */
}T_PageLayout, *PT_PageLayout;

typedef struct PageAction {
	char *name;            /* 页面名字 */
	void (*Run)(PT_PageParams ptParentPageParams);  /* 页面的运行函数 */
	int (*GetInputEvent)(PT_PageLayout ptPageLayout, PT_InputEvent ptInputEvent);  /* 获得输入数据的函数 */
	int (*Prepare)(void);         /* (未实现)后台准备函数: 为加快程序运行而同时处理某些事情 */
	struct PageAction *ptNext;    /* 链表 */
}T_PageAction, *PT_PageAction;

/* 页面配置信息 */
typedef struct PageCfg {
	int iIntervalSecond;      /* 连播模式下图片的显示间隔 */
	char strSeletedDir[256];  /* 连播模式下要显示哪个目录下的图片 */ 
}T_PageCfg, *PT_PageCfg;



//#define ID(name)   (int(name[0]) + int(name[1]) + int(name[2]) + int(name[3]))

/**********************************************************************
 * 函数名称: ID
 * 功能描述: 根据名字算出一个唯一的整数,它用来标识VideoMem中的显示数据
 * 输入参数: strName - 名字
 * 输出参数: 无
 * 返 回 值: 一个唯一的整数
 * 修改日期        版本号     修改人	      修改内容
 * -----------------------------------------------
 * 2013/02/08	     V1.0	  韦东山	      创建
 ***********************************************************************/
int ID(char *strName);

/**********************************************************************
 * 函数名称: MainPageInit
 * 功能描述: 注册"主页面"
 * 输入参数: 无
 * 输出参数: 无
 * 返 回 值: 0 - 成功, 其他值 - 失败
 * 修改日期        版本号     修改人	      修改内容
 * -----------------------------------------------
 * 2013/02/08	     V1.0	  韦东山	      创建
 ***********************************************************************/
int MainPageInit(void);

/**********************************************************************
 * 函数名称: SettingPageInit
 * 功能描述: 注册"setting页面"
 * 输入参数: 无
 * 输出参数: 无
 * 返 回 值: 0 - 成功, 其他值 - 失败
 * 修改日期        版本号     修改人	      修改内容
 * -----------------------------------------------
 * 2013/02/08	     V1.0	  韦东山	      创建
 ***********************************************************************/
int SettingPageInit(void);

/**********************************************************************
 * 函数名称: IntervalPageInit
 * 功能描述: 注册"interval页面"
 * 输入参数: 无
 * 输出参数: 无
 * 返 回 值: 0 - 成功, 其他值 - 失败
 * 修改日期        版本号     修改人	      修改内容
 * -----------------------------------------------
 * 2013/02/08	     V1.0	  韦东山	      创建
 ***********************************************************************/
int IntervalPageInit(void);

/**********************************************************************
 * 函数名称: BrowsePageInit
 * 功能描述: 注册"浏览页面"
 * 输入参数: 无
 * 输出参数: 无
 * 返 回 值: 0 - 成功, 其他值 - 失败
 * 修改日期        版本号     修改人	      修改内容
 * -----------------------------------------------
 * 2013/02/08	     V1.0	  韦东山	      创建
 ***********************************************************************/
int BrowsePageInit(void);

/**********************************************************************
 * 函数名称: AutoPageInit
 * 功能描述: 注册"连播页面"
 * 输入参数: 无
 * 输出参数: 无
 * 返 回 值: 0 - 成功, 其他值 - 失败
 * 修改日期        版本号     修改人	      修改内容
 * -----------------------------------------------
 * 2013/02/08	     V1.0	  韦东山	      创建
 ***********************************************************************/
int AutoPageInit(void);

/**********************************************************************
 * 函数名称: ManualPageInit
 * 功能描述: 注册"manual页面"
 * 输入参数: 无
 * 输出参数: 无
 * 返 回 值: 0 - 成功, 其他值 - 失败
 * 修改日期        版本号     修改人	      修改内容
 * -----------------------------------------------
 * 2013/02/08	     V1.0	  韦东山	      创建
 ***********************************************************************/
int ManualPageInit(void);

/**********************************************************************
 * 函数名称: RegisterPageAction
 * 功能描述: 注册"页面模块", "页面模块"含有页面显示的函数
 * 输入参数: ptPageAction - 一个结构体,内含"页面模块"的操作函数
 * 输出参数: 无
 * 返 回 值: 0 - 成功, 其他值 - 失败
 * 修改日期        版本号     修改人	      修改内容
 * -----------------------------------------------
 * 2013/02/08	     V1.0	  韦东山	      创建
 ***********************************************************************/
int RegisterPageAction(PT_PageAction ptPageAction);

/**********************************************************************
 * 函数名称: PagesInit
 * 功能描述: 调用各个"页面模块"的初始化函数,就是注册它们
 * 输入参数: 无
 * 输出参数: 无
 * 返 回 值: 0 - 成功, 其他值 - 失败
 * 修改日期        版本号     修改人	      修改内容
 * -----------------------------------------------
 * 2013/02/08	     V1.0	  韦东山	      创建
 ***********************************************************************/
int PagesInit(void);

/**********************************************************************
 * 函数名称: GeneratePage
 * 功能描述: 从图标文件中解析出图像数据并放在指定区域,从而生成页面数据
 * 输入参数: ptPageLayout - 内含多个图标的文件名和显示区域
 *            ptVideoMem   - 在这个VideoMem里构造页面数据
 * 输出参数: 无
 * 返 回 值: 0      - 成功
 *            其他值 - 失败
 * 修改日期        版本号     修改人	      修改内容
 * -----------------------------------------------
 * 2013/02/08	     V1.0	  韦东山	      创建
 ***********************************************************************/
int GeneratePage(PT_PageLayout ptPageLayout, PT_VideoMem ptVideoMem);

/**********************************************************************
 * 函数名称: GenericGetInputEvent
 * 功能描述: 读取输入数据,并判断它位于哪一个图标上
 * 输入参数: ptPageLayout - 内含多个图标的显示区域
 * 输出参数: ptInputEvent - 内含得到的输入数据
 * 返 回 值: -1     - 输入数据不位于任何一个图标之上
 *            其他值 - 输入数据所落在的图标(PageLayout->atLayout数组的哪一项)
 * 修改日期        版本号     修改人	      修改内容
 * -----------------------------------------------
 * 2013/02/08	     V1.0	  韦东山	      创建
 ***********************************************************************/
int GenericGetInputEvent(PT_PageLayout ptPageLayout, PT_InputEvent ptInputEvent);

/**********************************************************************
 * 函数名称: Page
 * 功能描述: 根据名字取出指定的"页面模块"
 * 输入参数: pcName - 名字
 * 输出参数: 无
 * 返 回 值: NULL   - 失败,没有指定的模块, 
 *            非NULL - "页面模块"的PT_PageAction结构体指针
 * 修改日期        版本号     修改人	      修改内容
 * -----------------------------------------------
 * 2013/02/08	     V1.0	  韦东山	      创建
 ***********************************************************************/
PT_PageAction Page(char *pcName);

/**********************************************************************
 * 函数名称: TimeMSBetween
 * 功能描述: 两个时间点的间隔:单位ms
 * 输入参数: tTimeStart - 起始时间点
 *            tTimeEnd   - 结束时间点
 * 输出参数: 无
 * 返 回 值: 间隔,单位ms
 * 修改日期        版本号     修改人	      修改内容
 * -----------------------------------------------
 * 2013/02/08	     V1.0	  韦东山	      创建
 ***********************************************************************/
int TimeMSBetween(struct timeval tTimeStart, struct timeval tTimeEnd);

/**********************************************************************
 * 函数名称: GetPageCfg
 * 功能描述: 获得页面的配置参数,
 *            对于连续播放页面,它需要得到2个参数:播放哪个目录下的图片,图片之间的播放间隔
 * 输入参数: 无
 * 输出参数: ptPageCfg - 内含得到的参数
 * 返 回 值: 无
 * 修改日期        版本号     修改人	      修改内容
 * -----------------------------------------------
 * 2013/02/08	     V1.0	  韦东山	      创建
 ***********************************************************************/
void GetPageCfg(PT_PageCfg ptPageCfg);

#endif /* _PAGE_MANAGER_H */

page中的各个页面
https://gitee.com/super_glob/project_1_ebook/tree/master/page

file目录

Makefile

obj-y += file.o

file.h

#ifndef _FILE_H
#define _FILE_H

#include <stdio.h>

typedef struct FileMap {
	char strFileName[256];   /* 文件名 */
	// int iFd; 
	FILE * tFp;              /* 文件句柄 */
	int iFileSize;           /* 文件大小 */
	unsigned char *pucFileMapMem;  /* 使用mmap函数映射文件得到的内存 */
}T_FileMap, *PT_FileMap;

/* 文件类别 */
typedef enum {
	FILETYPE_DIR = 0,  /* 目录 */
	FILETYPE_FILE,     /* 文件 */
}E_FileType;

/* 目录里的内容 */
typedef struct DirContent {
	char strName[256];     /* 名字 */
	E_FileType eFileType;  /* 类别 */	
}T_DirContent, *PT_DirContent;

/**********************************************************************
 * 函数名称: MapFile
 * 功能描述: 使用mmap函数映射一个文件到内存,以后就可以直接通过内存来访问文件
 * 输入参数: ptFileMap - 内含文件名strFileName
 * 输出参数: ptFileMap - tFp           : 所打开的文件句柄
 *                        iFileSize     : 文件大小
 *                        pucFileMapMem : 映射内存的首地址
 * 返 回 值: 0      - 成功
 *            其他值 - 失败
 * 修改日期        版本号     修改人	      修改内容
 * -----------------------------------------------
 * 2013/02/08	     V1.0	  韦东山	      创建
 ***********************************************************************/
int MapFile(PT_FileMap ptFileMap);

/**********************************************************************
 * 函数名称: UnMapFile
 * 功能描述: MapFile函数的清理函数
 * 输入参数: ptFileMap - 内含所打开/映射的文件信息
 * 输出参数: 无
 * 返 回 值: 无
 * 修改日期        版本号     修改人	      修改内容
 * -----------------------------------------------
 * 2013/02/08	     V1.0	  韦东山	      创建
 ***********************************************************************/
void UnMapFile(PT_FileMap ptFileMap);

/**********************************************************************
 * 函数名称: GetDirContents
 * 功能描述: 把某目录下所含的顶层子目录、顶层文件都记录下来,并且按名字排序
 * 输入参数: strDirName - 目录名(含绝对路径)
 * 输出参数: pptDirContents - (*pptDirContents)指向一个PT_DirContent数组,
 *                             (*pptDirContents)[0,1,...]指向T_DirContent结构体,
 *                             T_DirContent中含有"目录/文件"的名字等信息
 *            piNumber       - strDirName下含有多少个"顶层子目录/顶层文件",
 *                             即数组(*pptDirContents)[0,1,...]有多少项
 * 返 回 值: 0 - 成功
 *            1 - 失败
 * 修改日期        版本号     修改人	      修改内容
 * -----------------------------------------------
 * 2013/02/08	     V1.0	  韦东山	      创建
 ***********************************************************************/
int GetDirContents(char *strDirName, PT_DirContent **pptDirContents, int *piNumber);

/**********************************************************************
 * 函数名称: FreeDirContents
 * 功能描述: GetDirContents的清理函数,用来释放内存
 * 输入参数: aptDirContents - 指向PT_DirContent数组
 *            iNumber        - 有多少数组项
 * 输出参数: 无
 * 返 回 值: 无
 * 修改日期        版本号     修改人	      修改内容
 * -----------------------------------------------
 * 2013/02/08	     V1.0	  韦东山	      创建
 ***********************************************************************/
void FreeDirContents(PT_DirContent *aptDirContents, int iNumber);

/**********************************************************************
 * 函数名称: GetFilesIndir
 * 功能描述: 以深度优先的方式获得目录下的文件 
 *            即: 先获得顶层目录下的文件, 再进入一级子目录A
 *                再获得一级子目录A下的文件, 再进入二级子目录AA, ...
 *                处理完一级子目录A后, 再进入一级子目录B
 *
 * "连播模式"下调用该函数获得要显示的文件
 * 有两种方法获得这些文件:
 * 1. 事先把所有文件的名字保存到某个缓冲区中
 * 2. 用到时再去搜索取出若干个文件名
 * 第1种方法比较简单,但是当文件很多时有可能导致内存不足.
 * 我们使用第2种方法:
 * 假设某目录(包括所有子目录)下所有的文件都给它编一个号
 *
 * 输入参数:strDirName            : 要获得哪个目录下的内容 
 *           piStartNumberToRecord : 从第几个文件开始取出它们的名字
 *           iFileCountTotal       : 总共要取出多少个文件的名字
 * 输出参数:piFileCountHaveGet    : 已经得到了多少个文件的名字
 *           apstrFileNames[][256] : 用来存储搜索到的文件名
 * 输出/输出参数:
 *           piCurFileNumber       : 当前搜索到的文件编号
 * 返 回 值:0 - 成功
 *           1 - 失败
 * 修改日期        版本号     修改人	      修改内容
 * -----------------------------------------------
 * 2013/02/08	     V1.0	  韦东山	      创建
 ***********************************************************************/
int GetFilesIndir(char *strDirName, int *piStartNumberToRecord, int *piCurFileNumber, int *piFileCountHaveGet, int iFileCountTotal, char apstrFileNames[][256]);

#endif /* _FILE_H */

file.c

代码:<https://gitee.com/super_glob/project_1_ebook/blob/master/file.c>

main函数

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <config.h>
#include <encoding_manager.h>
#include <fonts_manager.h>
#include <disp_manager.h>
#include <input_manager.h>
#include <pic_operation.h>
#include <render.h>
#include <string.h>
#include <picfmt_manager.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>


/* digitpic <freetype_file> */
int main(int argc, char **argv)
{	
	int iError;

	/* 初始化调试模块: 可以通过"标准输出"也可以通过"网络"打印调试信息
	* 因为下面马上就要用到DBG_PRINTF函数, 所以先初始化调试模块
	*/

	/* 注册调试通道 */
	DebugInit();

	/* 初始化调试通道 */
	InitDebugChanel();

	if (argc != 2)
	{
		DBG_PRINTF("Usage:
");
		DBG_PRINTF("%s <freetype_file>
", argv[0]);
		return 0;
	}

	/* 注册显示设备 */
	DisplayInit();
	/* 可能可支持多个显示设备: 选择和初始化指定的显示设备 */
	SelectAndInitDefaultDispDev("fb");

	/* 
	* VideoMem: 为加快显示速度,我们事先在内存中构造好显示的页面的数据,
				(这个内存称为VideoMem)
	*           显示时再把VideoMem中的数据复制到设备的显存上
	* 参数的含义就是分配的多少个VideoMem
	* 参数可取为0, 这意味着所有的显示数据都是在显示时再现场生成,然后写入显存
	*/
	AllocVideoMem(5);

	/* 注册输入设备 */
	InputInit();
	/* 调用所有输入设备的初始化函数 */
	AllInputDevicesInit();

	/* 注册字库模块 */
	iError = FontsInit();
	if (iError)
	{
		DBG_PRINTF("FontsInit error!
");
	}

	/* 设置freetype字库所用的文件和字体尺寸 */
	iError = SetFontsDetail("freetype", argv[1], 24);
	if (iError)
	{
		DBG_PRINTF("SetFontsDetail error!
");
	}

	/* 注册图片文件解析模块 */
	PicFmtsInit();

	/* 注册页面 */
	PagesInit();

	/* 运行主页面 */
	Page("main")->Run(NULL);
		
	return 0;
}
原文地址:https://www.cnblogs.com/huangdengtao/p/12391455.html