/*************************************************************************************************************
* 文件名 : JpegCodec.c
* 功能 : S3C6410 JPEG解码底层驱动函数
* 作者 : cp1300@139.com
* 创建时间 : 2012年9月20日20:59
* 最后修改时间 : 2012年12月02日
* 详细 : JPEG硬解码
* 通过S3C6410 DATASHEETV1.2版以及官方WINCE的JPEG驱动的分析,得出结论,S3C6410的JPEG解码模块不支持硬件控制自动解码
* 只能使用软件控制解码模式
* 20121202:修复连续解码BUG,目前有少数jpeg420,jpeg444会解码出错,就像windows也有可能有不支持的jpeg图片一样,少数图片硬解码
* 失败可以尝试使用软解码即可。
* 20121225:发现JPEG必须16字节(128位)地址对齐,否则可能会出现解码失败问题。
* 20130113:增加尺寸非8或16倍数的jpeg图片解码功能
* 20130113:将程序外部依赖降低,目前只依赖外部的数据类型定义(高类聚,低耦合),打印调试也依赖外部,不用可以修改宏,JPEG_DBUG=0来取消,方便移植。
*************************************************************************************************************/
#include "JpegCodec.h"
#include "jpeg_tables.h"
//调试宏开关
#define JPEG_DBUG 0
#if JPEG_DBUG
#include "system.h"
#define jpeg_debug(format,...) uart_printf(format,##__VA_ARGS__)
#else
#define jpeg_debug(format,...) /\
/
#endif //JPEG_DBUG
//jpeg编解码模式配置
#define COEF1_RGB_2_YUV 0x4d971e
#define COEF2_RGB_2_YUV 0x2c5783
#define COEF3_RGB_2_YUV 0x836e13
#define ENABLE_MOTION_ENC (0x1<<3) //使能动态编码
#define DISABLE_MOTION_ENC (0x0<<3)
#define ENABLE_HW_DEC (0x1<<2)
#define DISABLE_HW_DEC (0x0<<2)
#define ENABLE_MOTION_DEC (0x1<<0) //使能动态解码
#define DISABLE_MOTION_DEC (0x0<<0)
#define INCREMENTAL_DEC (0x1<<3) //增量解码模式
#define NORMAL_DEC (0x0<<3) //正常解码模式
#define YCBCR_MEMORY (0x1<<5)
#define ENABLE_IRQ (0xf<<3)
//等待超时定义
#define WaitTimeOut 0xffffff //等待超时计数器
//定义最大图像宽高度
#define MAX_JPG_WIDTH 4096
#define MAX_JPG_HEIGHT 4096
//JPEG寄存器结构定义
typedef struct
{
u32 Mode; //模式寄存器
u32 Status; //状态寄存器
u32 QTblNo;
u32 RSTPos;
u32 Vertical; //垂直分辨率
u32 Horizontal; //水平分辨率
u32 DataSize; //压缩数据字节数
u32 IRQ; //中断设置寄存器
u32 IRQStatus; //中断状态寄存器 0x20
u32 Reserved0[247];
u32 QTBL0[64]; //0x400
u32 QTBL1[64];
u32 QTBL2[64];
u32 QTBL3[64];
u32 HDCTBL0[16]; //0x800
u32 HDCTBLG0[12];
u32 Reserved1[4];
u32 HACTBL0[16];
u32 HACTBLG0[162]; //0x8c0
u32 Reserved2[46];
u32 HDCTBL1[16]; //0xc00
u32 HDCTBLG1[12];
u32 Reserved3[4];
u32 HACTBL1[16];
u32 HACTBLG1[162]; //0xcc0
u32 Reserved4[46];
u32 ImageAddr0; //目的图像地址1
u32 ImageAddr1; //目的图像地址2
u32 JpegAddr0; //源JPEG图像地址1
u32 JpegAddr1; //源JPEG图像地址2
u32 Start; //JPEG解码开始
u32 ReStart; //重新开始JPEG解码
u32 SofReset; //JPEG复位
u32 Cntl; //控制寄存器
u32 COEF1;
u32 COEF2;
u32 COEF3;
u32 Misc; //杂项寄存器
u32 FramIntv;
}JPEG_TypeDef;
//定义JPEG文件标记
enum
{
UNKNOWN,
BASELINE = 0xC0,
EXTENDED_SEQ = 0xC1,
PROGRESSIVE = 0xC2
}JPG_SOF_MARKER;
//S3C6410 jpeg编解码器基址
#define JPEG_BASE 0x78800000
//寄存器结构指针
#define JPEG ((JPEG_TypeDef *)JPEG_BASE)
//内部静态函数声明
static void JPEG_Reset(void); //JPEG解码器软件复位
static JPEG_TYPE JPEG_GetJpegType(void); //获取JPEG采样模式
static void JPEG_GetWidthHeight(u16* width, u16* height);//获取图像大小
static JPEG_ERROR JPEG_WaitForIRQ(void); //等待中断,并返回状态
static bool JPEG_CorrectHeader(JPEG_TYPE jpegType, u16 *width, u16 *height);
static void JPEG_WriteHeader(u32 JpgAddr, u32 fileSize, u16 width, u16 height);
static void JPEG_WriteYUV(u32 ImageAddr, u16 width, u16 orgwidth, u16 height, u16 orgheight);
static void JPEG_MemMove(u8* dest, u8* src,u32 count);
/*************************************************************************************************************************
*函数 : void JPEG_Init(void)
*功能 : JPEG解码初始化
*参数 : 无
*返回 : 无
*依赖 : 底层宏定义
*作者 : cp1300@139.com
*时间 : 20120920
*最后修改时间 : 20120923
*说明 : 无
*************************************************************************************************************************/
void JPEG_Init(void)
{
//rCLK_DIV0 |= 0x03 << 24;
//Set_GateClk(SCLK_JPEG,ENABLE); //使能JPEG模块时钟
}
/*************************************************************************************************************************
*函数 : static void JPEG_Reset(void)
*功能 : JPEG解码器软件复位
*参数 : 无
*返回 : 无
*依赖 : 底层宏定义
*作者 : cp1300@139.com
*时间 : 20120920
*最后修改时间 : 2010113
*说明 : 无
*************************************************************************************************************************/
static void JPEG_Reset(void)
{
JPEG->SofReset = 0;
}
/*************************************************************************************************************************
*函数 : static JPEG_TYPE JPEG_Reset(void)
*功能 : 获取JPEG采样模式
*参数 : 无
*返回 : JPEG类型,见定义
*依赖 : 底层宏定义
*作者 : cp1300@139.com
*时间 : 20120920
*最后修改时间 : 2010113
*说明 : 编码模式只有0x1,0x2两种模式
*************************************************************************************************************************/
static JPEG_TYPE JPEG_GetJpegType(void)
{
switch (JPEG->Mode & 0x07) //通过判断0-2BIT
{
case 0 : return TYPE_JPEG_444; //色度4:4:4格式
case 1 : return TYPE_JPEG_422; //色度4:2:2格式
case 2 : return TYPE_JPEG_420; //色度4:2:0格式
case 3 : return TYPE_JPEG_400; //灰色格式(单一组成)
case 6 : return TYPE_JPEG_411; //色度4:1:1格式
default : return TYPE_JPEG_UNKNOWN;
}
}
/*************************************************************************************************************************
*函数 : static void JPEG_GetWidthHeight(u16* width, u16* height)
*功能 : 获取图像尺寸大小
*参数 : HSize:图像宽度缓冲区指针;VSize:图像高度缓冲区指针
*返回 : 无
*依赖 : 底层宏定义
*作者 : cp1300@139.com
*时间 : 20120920
*最后修改时间 : 2010113
*说明 : 16BIT
*************************************************************************************************************************/
static void JPEG_GetWidthHeight(u16* width, u16* height)
{
*width = JPEG->Horizontal; //在水平方向上定义图像大小的值
*height = JPEG->Vertical; //在垂直方向上定义图像大小的值
}
/*************************************************************************************************************************
*函数 : u32 JPEG_GetYUVSize(JPEG_TYPE jpegType,u16 width, u16 height)
*功能 : 获取解码后数据大小
*参数 : jpegType:jpeg图像类型,width,height:图像尺寸
*返回 : 无
*依赖 : 底层宏定义
*作者 : cp1300@139.com
*时间 : 2010113
*最后修改时间 : 2010113
*说明 : 无
*************************************************************************************************************************/
u32 JPEG_GetYUVSize(JPEG_TYPE jpegType,u16 width, u16 height)
{
switch(jpegType)
{
case TYPE_JPEG_444 : return(width*height*3);
case TYPE_JPEG_422 : return(width*height*2);
case TYPE_JPEG_420 :
case TYPE_JPEG_411 : return((width*height) + (width*height>>1));
case TYPE_JPEG_400 : return(width*height);
default : return(0);
}
}
/*************************************************************************************************************************
*函数 : void JPEG_ReadClearStatus(u8* Status, u8* IrqStatus)
*功能 : 读取并清除JPEG状态
*参数 : Status:解码器状态缓冲区指针;IrqStatus:中断�