JPG(JPEG)是最常见的图片格式,其具有出色的压缩能力和很小的图象失真。因性能优异,JPG现已成为计算机的标准图象格式。且随着枝术的进步,JPG的算法也有了进一步的发展。
关键字 JPG 解码 MCU 图像显示
1 子程序说明
1.1 软件说明
整个库包含2个文件:一个是库文件“JPG_Decode_061.lib”,另一个是这个相应的外部函数申明的头文件“JPG_Decode.h”。用户在使用时一定要有这两个文件,同时应在用户自己的代码中引用“JPG_Decode.h”这个头文件。
“JPG_Decode_061.lib”这个库包含多个函数,其中只有3个对用户可见。JPG_Decode.h有各个函数的原型和参数功能说明。本文主要是JPG解码库的函数说明和使用说明,并用一个简单的例子来说明这个库的使用方法。
这个库会引用一个外部函数“void JPG_Read_File(unsigned char *Data,char Num)”和“unsigned char NEXTBYTE(void)”,这两个函数的定义与存贮介质相关,需要用户根据自已所用存贮介质进行编写。
1.2 库变量说明
unsigned char JPG_Y_Temp[4][64]; //IDCT变换后的亮度参数
unsigned char JPG_Cb_Temp[2][64]; //IDCT变换后的色差参数 Cb
unsigned char JPG_Cr_Temp[2][64]; //IDCT变换后的色差参数 Cr
unsigned int RGB_out[64]; //解码后的16位真彩数据,这个数组里存了一个8X8的图象块
RGB_out[]里的数据只用在调用JPG_YCbCr_RGB()后才是解码后的16位真彩数据,在其它时候它用作库内部暂存使用。因此在调用JPG_YCbCr_RGB()后,RGB_out[]里的数据需要立即显示或是读取后方能进行下一次解码,不然,当前解码数据将被丢弃。
extern struct
{
int Width_Size; //图象宽度
int High_Sine; //图象高度
char G_RGB; //图象属性,为1时为灰度图象,为3时为真彩图象
char MCU_Decode_Step;//当前计算的图象块指示器
int Width_MCU_Num; //水平方向的MCU数量
int High_MCU_Num; //垂直方向的MCU数量
int MCU_Loop_Num; //MCU单元标记重复出现的长度
char JPG_Pq; //量化表精度 0表示8Bit, 1表示16Bit
char JPG_Tq; //量化表个数.0~3通常为0~1.也就是最多两个量化表
char H_MAX; //水平方向采样系数的最大值,这两个值通常是相等的
char V_MAX; //垂直方向采样系数的最大值
} JPG_Head;
JPG_Head里的数据只有在调用了JPG_Decode()方才有效。有关JPG_Decode()的说明请参考后API函数说明
1.3 档案构成
文件名称 | 功能 | 类型 |
JPG_Decode_061.lib | JPG解码库,只适用SPCE061 | Lib |
JPG_Decode.h | API引用和相关参数定义 | H |
1.4 API函数说明
JPG_Decode() | |
原 形 | char JPG_Decode(unsigned int *File) |
描 述 | JPG文件结构解析、解码用的各种表格和参数初始化 |
输入参数 | " File ": 指向所需要解码JPG文件的首指针 |
输出参数 | 文件结构解析状态 |
头 文 件 | JPG_Decode.h |
库 文 件 | JPG_Decode_061.lib |
注意事项 | 无 |
例 子 | SPMC75_SPWM_TMR_Init(1,12); |
MCU_Decode() | |
原 形 | void MCU_Decode(void) |
描 述 | 完成一个MCU单元的解码,并将解码后YCbCr格式的图象数据存于暂存中。 |
输入参数 | 无 |
输出参数 | 无 |
头 文 件 | JPG_Decode.h |
库 文 件 | JPG_Decode_061.lib |
注意事项 | void MCU_Decode(void)一次只能解码一个MCU单元,需要多次调用才能完成一幅图象的解码。 |
例 子 | MCU_Decode (); |
JPG_YCbCr_RGB() | |
原 形 | void JPG_YCbCr_RGB(void) |
描 述 | 完成8X8图象单元的色彩空间变换。将YCbCr格式的图象变换换到RGB 565格式。 |
输入参数 | 无 |
输出参数 | 无 |
头 文 件 | JPG_Decode.h |
库 文 件 | JPG_Decode_061.lib |
注意事项 | 无 |
例 子 | JPG_YCbCr_RGB(); |
JPG_Read_File() | |
原 形 | void JPG_Read_File(unsigned char *Data,char Num) |
描 述 | 从当前正在解码的JPG文件中读取Num字节的数据,并将其存在Data所指向的数组中 |
输入参数 | "Data": 指向数据存贮数组的指针 |
输出参数 | 无 |
头 文 件 | JPG_Decode.h |
库 文 件 | JPG_Decode_061.lib |
注意事项 | 这个函数是需要用户自定义的,是本解码库与用户应用的一个外部接口。通过它可以实现不同存贮介质的解码。 |
例 子 | extern unsigned int *JPG_File_Pointer; void JPG_Read_File(unsigned char *Data,char Num) |
NEXTBYTE() | |
原 形 | unsigned char NEXTBYTE(void) |
描 述 | 从当前正在解码的JPG文件中读取1字节的数据 |
输入参数 | 无 |
输出参数 | 读取的这字节数据 |
头 文 件 | JPG_Decode.h |
库 文 件 | JPG_Decode_061.lib |
注意事项 | 无 |
例 子 | unsigned char NEXTBYTE(void) |
2 使用说明
2.1 新建工程
在IDE环境下新建工程并保存。
2.2 库链接
1.将JPG解码库文件JPG_Decode_061.lib考到刚才新建工程的目录下,同时还有相应的头文件JPG_Decode.h也考到同一目录下;
2.打开【Project】菜单下的【Setting】选项,进入【Link】标签;
3.点击【Link】标签下Library Modules 后面的文件夹标志,找到JPG_Decode_061.lib所在路径并点击 “打开”;
4.点 “OK” 退出【Setting】;
2.3 JPG图象资源加载
打开IDE下的资源窗口,选择添加新文件
浏览并选中想要添加的JPG文件,并点击打开
1.解析需要解码的JPG文件 JPG_Decode(RES_BANWAN_JPG_SA);
2.根据JPG_Decode()获得的图象信息,调用JPG_MCU_Decode()实现MCU单元解码。解一幅图象根据图象的大小的不同需要多次调用JPG_MCU_Decode()方能完成整个图象的解码。需要注意的是:灰度图象的一个MCU单元的大小是8X8,而彩色图象是16X16;
3.根据图象MCU单元的大小进行色彩空间变换。通常灰度图象一个MCU单元只有一个8X8图象单元,调用一次JPG_MCU_Decode(),只需要调用一次JPG_YCbCr_RGB()就可以。而彩色图象的一个MCU单元是16X16,相当于4个8X8的图象单元,调用一次JPG_MCU_Decode(),需要调用4次JPG_YCbCr_RGB(),才能将一个MCU单元解码完毕;
4.建立void JPG_Read_File(unsigned char *Data,char Num):
extern unsigned int *JPG_File_Pointer;
extern char File_Pointer_Flag;
void JPG_Read_File(unsigned char *Data,char Num)
{
char i;
for(i=0;i<Num;i++)
{
if(File_Pointer_Flag == 0)
{
Data[i] = (unsigned char)((*JPG_File_Pointer)&0xff);
File_Pointer_Flag = 1;
}
else
{
Data[i] = (unsigned char)((*JPG_File_Pointer++) >> 8);
File_Pointer_Flag = 0;
}
}
这个函数需要根据你所用的存贮介质来编写。上面的代码是图象存贮在061的内部Flash时的情况。
5.建立unsigned char NEXTBYTE(void):
unsigned char NEXTBYTE(void)
{
if(File_Pointer_Flag == 0)
{
File_Pointer_Flag = 1;
return (unsigned char)((*JPG_File_Pointer)&0xff);
}
else
{
File_Pointer_Flag = 0;
return (unsigned char)((*JPG_File_Pointer++) >> 8);
}
}
这个函数需要根据你所用的存贮介质来编写。上面的代码是图象存贮在061的内部Flash时的情况。
3 使用范例
3.1 DEMO程序
请下载demo.rar
4 注意事项
这个JPG解码库是针对MCU写的,为了节约资源,它实际是标准JPG解码的一个子集。只实现了部分JPG解码的功能。本库并不能支持所有格式的JPG图片,但绝大部分图片是支持的(经Windows的绘图存贮的JPG图片都支持)。同时由于MCU资源有限,实际解码的JPG文件需要用专用JPG垃圾信息清理软件清理一下(这种软件并不破坏原文件的文件结构),可以放心使用。使用它主要是因为象Photoshop等软件处理后的JPG图片里会包含与原图片不相关的各种垃圾信息,当原图片不是太大时,这些信息可能比图象本身还要大得多。
此外,铭正同创拥有自主的JPG解码源代码,可快速针对不同的MCU/CPU平台制作出专有的应用库,这些技术将会随着产品提供给特定的用户;而为了方便用户作技术评估,我们提供了基于凌阳unSP系列单片机(SPCE061A)的JPG解码应用库,以及Demo程序,感兴趣的朋友可以到资料下载栏目下载该范例。