S3C6410 裸机硬件JPEG解码
S3C6410 裸机硬件JPEG解码
2012年12月25日,晚上我找到问题所在了,JPEG解码源图像地址必须是16字节(128位)对齐的,也就是最低4位必须为0,这个害的我好久,还好终于解决了。
修复了已知的bug;
这个是我实验用的原图,用工具把他变成了数组后直接放在程序里面了.
解码后的图片
附上代码
/*************************************************************************************************************
* 文件名 : 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:中断状态缓冲区指针
*返回 : 无
*依赖 : 底层宏定义
*作者 : cp1300@139.com
*时间 : 20120920
*最后修改时间 : 2010113
*说明 : JPGSTS和JPGIRQ;JPGIRQ读取后自动清除
* JPGIRQ: BIT6结果状态 0:不正常的处理结束; 1:正常的处理完成
* BIT4位流的错误状态。只有在解压缩期间有效。0:在被压缩的文件上,没有语法错误。1:在被压缩的文件上,有语法错误。
* BIT3标题状态。只有在解压缩期间有效。0:图像大小和取样因素值不可读。1:图像大小和取样因素值可读。
*************************************************************************************************************************/
void JPEG_ReadClearStatus(u8* Status, u8* IrqStatus)
{
*Status = JPEG->Status;
*IrqStatus = JPEG->IRQStatus & ((1<<6)|(1<<4)|(1<<3));
}
/*************************************************************************************************************************
*函数 : static JPEG_ERROR JPEG_WaitForIRQ(void)
*功能 : 等待中断,并返回状态
*参数 : 无
*返回 : 返回中断状态,见定义
*依赖 : 底层宏定义
*作者 : cp1300@139.com
*时间 : 20120922
*最后修改时间 : 2010113
*说明 : 通过判断JPGIRQ中断寄存器的值返回相应状态
*************************************************************************************************************************/
static JPEG_ERROR JPEG_WaitForIRQ(void)
{
vu32 TimeOut = WaitTimeOut; //初始化计数器值
vu8 IRQStatus,Status;
JPEG_ERROR error;
do
{
IRQStatus = JPEG->IRQStatus; //读取中断状态寄存器,并消除状态
TimeOut --; //计数器自减
}
while((IRQStatus == 0) && TimeOut); //当发生中断或者计数器为0时退出等待
IRQStatus &= ((1<<6)|(1<<4)|(1<<3));
switch (IRQStatus) //判断中断状态
{
case 0x00 : error = JPEG_WAIT_TIME_OUT;break; //超时错误
case 0x40 : error = JPEG_OK;break; //正常完成
case 0x08 : error = JPEG_HEADER_OK;break; //头分析完成,可以读取大小以及采样信息
case 0x10 : error = JPEG_BITSTRE_ERROR;break; //语法错误
case 0x18 : error = JPEG_BITSTRE_ERROR;break; //语法错误
default : error = JPEG_OTHER_ERROR;break; //其它错误
}
Status = JPEG->Status;
return error;
}
/*************************************************************************************************************************
*函数 : static void JPEG_DecodeHeader(u32 JpegAddr)
*功能 : 开始解码JPEG头部信息(软件控制解码)
*参数 : JpegAddr: jpeg图像地址
*返回 : 无
*依赖 : 底层宏定义
*作者 : cp1300@139.com
*时间 : 20120920
*最后修改时间 : 2010113
*说明 : 用于软件解码的第一步,用于获取JPEG分辨率以及采样模式信息
*************************************************************************************************************************/
static void JPEG_DecodeHeader(u32 JpegAddr)
{
JPEG->JpegAddr0 = JpegAddr;
JPEG->JpegAddr1 = JpegAddr; //jpeg图片数据地址
JPEG->Mode = 0x8; //设置为解码模式
JPEG->IRQ = ENABLE_IRQ; //使能中断
JPEG->Cntl = DISABLE_HW_DEC; //解码JPEG头部
JPEG->Misc = (NORMAL_DEC | YCBCR_MEMORY);
JPEG->Start = 1; //开始JPEG处理
}
/*************************************************************************************************************************
*函数 : static void JPEG_DecodeBody(u32 ImageAddr)
*功能 : 开始JPEG主体解码(软件控制解码)
*参数 : ImageAddr: 解码后图像地址
*返回 : 无
*依赖 : 底层宏定义
*作者 : cp1300@139.com
*时间 : 20120920
*最后修改时间 : 2010113
*说明 : 软件控制解码的第二步,一定要先调用JPEG_StartParsingHeader
*************************************************************************************************************************/
static void JPEG_DecodeBody(u32 ImageAddr)
{
JPEG->ImageAddr0 = ImageAddr;
JPEG->ImageAddr1 = ImageAddr; //解码数据缓冲器地址
JPEG->Cntl = 0; //解码JPEG头部
JPEG->Misc = 0;
JPEG->ReStart = 1; //开始主解码处理
}
/*************************************************************************************************************************
*函数 : JPEG_ERROR JPEG_DecodeOneFrame(u32 JpgAddr, u32 ImageAddr, u32 jpegSize, JPEG_INFO *JpegInfo)
*功能 : 开始解码一帧JPEG
*参数 : JpegAddr: jpeg图像地址
* ImageAddr: 解码后图像地址
* jpegSize: 图片数据大小
* JpegInfo: 图像信息结构指针
*返回 : JPEG_ERROR
*依赖 : JPEG_StartParsingHeader;JPEG_StartDecodingBody
*作者 : cp1300@139.com
*时间 : 20120920
*最后修改时间 : 2010113
*说明 : 软件控制解码模式
* 修改源图像地址128位对齐bug
* 20120113:增加尺寸非8或16倍数的jpeg图片解码功能,需要传递一个参数,即图片大小,通过FileSize传递
* 非对齐的jpeg解码效率将低于对齐的图片,由于解码前需要先改写数据。
*************************************************************************************************************************/
JPEG_ERROR JPEG_DecodeOneFrame(u32 JpgAddr, u32 ImageAddr, u32 jpegSize, JPEG_INFO *JpegInfo)
{
JPEG_ERROR status;
u16 width,height;
bool headerFixed = FALSE;
#if JPEG_DBUG
const char *JpegType[6] = {"JPEG 4:4:4","JPEG 4:2:2","JPEG 4:2:0","JPEG 4:0:0","JPEG 4:1:1","JPEG UNKNOWN"};
#endif
if(JpgAddr % 16) //源地址一定要是16字节(128位)对齐的,否则会出现各种意想不到的问题,这个问题困扰了我5个多月。
{
jpeg_debug("jpeg addr error\r\n");
return JPEG_OTHER_ERROR;
}
JpegInfo->FileSize = jpegSize; //存储图片大小
jpeg_debug("\r\n");
jpeg_debug("start jpeg decoding...\r\n");
JPEG_Reset();
JPEG_DecodeHeader(JpgAddr); //分析JPEG文信息
status = JPEG_WaitForIRQ(); //等待完成
if(status != JPEG_HEADER_OK) //图像分析错误
{
return status;
}
JpegInfo->Type = JPEG_GetJpegType(); //获取图片类型
jpeg_debug("Jpeg Mod:%s\r\n",JpegType[JpegInfo->Type]);
if(JpegInfo->Type == TYPE_JPEG_UNKNOWN) //未定义类型
{
return JPEG_TYPE_ERROR;
}
JPEG_GetWidthHeight(&(JpegInfo->Width),&(JpegInfo->Height)); //获取图片分辨率
width = JpegInfo->Width;
height = JpegInfo->Height;
if(!JPEG_CorrectHeader(JpegInfo->Type, &(JpegInfo->Width), &(JpegInfo->Height)))
{
JPEG_WriteHeader(JpgAddr,jpegSize,JpegInfo->Width, JpegInfo->Height);
headerFixed = TRUE;
}
jpeg_debug("jpeg image size %d*%d\r\n",JpegInfo->Width,JpegInfo->Height);
if(JpegInfo->Width <= 0 || JpegInfo->Width > MAX_JPG_WIDTH || JpegInfo->Height <= 0 || JpegInfo->Height > MAX_JPG_HEIGHT)
{
return JPEG_SIZE_ERROR;
}
if(headerFixed == TRUE)
{
JPEG_Reset();
JPEG_DecodeHeader(JpgAddr); //分析JPEG文信息
status = JPEG_WaitForIRQ(); //等待完成
if(status != JPEG_HEADER_OK) //图像分析错误
{
return status;
}
JPEG_DecodeBody(ImageAddr); //解码JPEG
status = JPEG_WaitForIRQ(); //等待完成
if(status == JPEG_OK)
{
jpeg_debug("Jpeg decode OK(%d)\r\n",status);
//JPEG_GetStreamLen(&(JpegInfo->DataSize)); //获取解码后图像大小
}
else
{
jpeg_debug("Jpeg decode error(%d)\r\n",status);
return status;
}
// for post processor, discard pixel
if(width % 4 != 0)
width = (width/4)*4;
if(height % 2 != 0)
height = (height/2)*2;
JPEG_WriteYUV(ImageAddr,JpegInfo->Width,width,JpegInfo->Height,height);
JpegInfo->Width = width;
JpegInfo->Height = height;
}
else
{
JPEG_DecodeBody(ImageAddr); //解码JPEG
status = JPEG_WaitForIRQ(); //等待完成
if(status == JPEG_OK)
{
jpeg_debug("Jpeg decode OK(%d)\r\n",status);
}
else
{
jpeg_debug("Jpeg decode error(%d)\r\n",status);
return status;
}
}
JpegInfo->DataSize = JPEG_GetYUVSize(JpegInfo->Type,JpegInfo->Width,JpegInfo->Height);
return status; //返回错误
}
/*************************************************************************************************************************
*函数 : JPEG_ERROR JPEG_EncodeOneFrame(u32 JpgAddr, u32 ImageAddr, JPEG_INFO *JpegInfo)
*功能 : 压缩一张JPEG
*参数 : JpegAddr: jpeg图像地址
* ImageAddr: 解码后图像地址
* JpegInfo: 图像信息结构指针
*返回 : JPEG_ERROR
*依赖 : 无
*作者 : cp1300@139.com
*时间 : 20130114
*最后修改时间 : 201310114
*说明 : 只支持YCbCr4:2:2,YCbCr4:2:0的输入格式
* 只测试了编码,能成功,但是没有生成jpeg文件进行测试,如果要生成jpeg文件应该还需要添加相应的文件头和尾部。
*************************************************************************************************************************/
JPEG_ERROR JPEG_EncodeOneFrame(u32 JpgAddr, u32 ImageAddr, JPEG_QUALITY_TYPE jpegQuality, JPEG_INFO *JpegInfo)
{
JPEG_ERROR status = JPEG_OK;
u32 i;
if(JpegInfo->Width <= 0 || JpegInfo->Width > MAX_JPG_WIDTH || JpegInfo->Height <= 0 || JpegInfo->Height > MAX_JPG_HEIGHT)
{
return JPEG_SIZE_ERROR;
}
JPEG_Reset();
JPEG->Mode = (JpegInfo->Type == TYPE_JPEG_422) ? (0x01 << 0) : (0x02 << 0); //亚抽样模式
JPEG->RSTPos = 2; // MCU inserts RST marker
JPEG->QTblNo = (1 << 12) | (1 << 14);
JPEG->Horizontal = JpegInfo->Width;
JPEG->Vertical = JpegInfo->Height;
JPEG->ImageAddr0 = ImageAddr;
JPEG->ImageAddr1 = ImageAddr;
JPEG->JpegAddr0 = JpgAddr;
JPEG->JpegAddr1 = JpgAddr;
JPEG->COEF1 = COEF1_RGB_2_YUV; // Coefficient value 1 for RGB to YCbCr
JPEG->COEF2 = COEF2_RGB_2_YUV; // Coefficient value 2 for RGB to YCbCr
JPEG->COEF3 = COEF3_RGB_2_YUV; // Coefficient value 3 for RGB to YCbCr
JPEG->Misc = (1<<5) | (0<<2);
JPEG->Cntl = DISABLE_MOTION_ENC;
// Quantiazation and Huffman Table setting
for (i=0; i<64; i++)
JPEG->QTBL0[i] = (u32)QTBL_Luminance[jpegQuality][i];
for (i=0; i<64; i++)
JPEG->QTBL1[i] = (u32)QTBL_Chrominance[jpegQuality][i];
for (i=0; i<16; i++)
JPEG->HDCTBL0[i] = (u32)HDCTBL0[i];
for (i=0; i<12; i++)
JPEG->HDCTBLG0[i] = (u32)HDCTBLG0[i];
for (i=0; i<16; i++)
JPEG->HACTBL0[i] = (u32)HACTBL0[i];
for (i=0; i<162; i++)
JPEG->HACTBLG0[i] = (u32)HACTBLG0[i];
JPEG->Start = 0;
status = JPEG_WaitForIRQ();
if(status == JPEG_OK)
{
jpeg_debug("Jpeg encode OK!(%d)\r\n",status);
JpegInfo->FileSize = JPEG->DataSize;
}
else
{
JpegInfo->FileSize = 0;
jpeg_debug("Jpeg encode error!(%d)\r\n",status);
}
return status;
}
/*************************************************************************************************************************
*函数 : static bool JPEG_CorrectHeader(JPEG_TYPE jpegType, u16 *width, u16 *height)
*功能 : 检查图像的宽高时候满足要求
*参数 : jpegType: jpeg类型,见JPEG_TYPE
* width: 图像宽度
* height: 图像高度
*返回 : TRUE:需要重写宽度,高度
* FALSE:无需重写宽度,高度
*依赖 : 无
*作者 : cp1300@139.com
*时间 : 20130113
*最后修改时间 : 20130113
*说明 : 直接由S3C6410官方代码移植而来
* 如果不满足要求,将计算最接近的满足要求的分辨率,JPEG分辨率需要能被8或者16整除,具体可以查阅相关资料
*************************************************************************************************************************/
static bool JPEG_CorrectHeader(JPEG_TYPE jpegType, u16 *width, u16 *height)
{
bool result = FALSE;
switch(jpegType){
case TYPE_JPEG_400 :
case TYPE_JPEG_444 :
{
if((*width % 8 == 0) && (*height % 8 == 0))
result = TRUE;
if(*width % 8 != 0)
*width += 8 - (*width % 8);
if(*height % 8 != 0)
*height += 8 - (*height % 8);
}break;
case TYPE_JPEG_422 :
{
if((*width % 16 == 0) && (*height % 8 == 0))
result = TRUE;
if(*width % 16 != 0)
*width += 16 - (*width % 16);
if(*height % 8 != 0)
*height += 8 - (*height % 8);
}break;
case TYPE_JPEG_420 :
case TYPE_JPEG_411 :
{
if((*width % 16 == 0) && (*height % 16 == 0))
result = TRUE;
if(*width % 16 != 0)
*width += 16 - (*width % 16);
if(*height % 16 != 0)
*height += 16 - (*height % 16);
}break;
default : break;
}
return(result);
}
/*************************************************************************************************************************
*函数 : static void JPEG_WriteHeader(u32 JpgAddr, u32 fileSize, u16 width, u16 height)
*功能 : 重写jpeg头部信息
*参数 : JpgAddr: jpeg文件的起始指针
* fileSize: jpeg文件大小
* width: jpeg文件宽度,需要重写的宽度
* height: jpeg文件高度,需要重写的宽度
*返回 : 无
*依赖 : 无
*作者 : cp1300@139.com
*时间 : 20130113
*最后修改时间 : 20130113
*说明 : 重写的只是内存中的数据
*************************************************************************************************************************/
static void JPEG_WriteHeader(u32 JpgAddr, u32 fileSize, u16 width, u16 height)
{
u32 i;
u8 *ptr = (u8 *)(JpgAddr + fileSize);
u8 *ptr2;
u8 *SOF1;
u8 *header;
jpeg_debug("DD::Header is not multiple of MCU\r\n");
for(i=0; i < fileSize; i++)
{
ptr--;
if(*ptr == 0xFF)
{
ptr2 = ptr+1;
if((*ptr2 == BASELINE) || (*ptr2 == EXTENDED_SEQ) || (*ptr2 == PROGRESSIVE))
{
jpeg_debug("jpeg match FFC0(i : %d)\r\n", i);
SOF1 = ptr2+1;
break;
}
}
}
jpeg_debug("jpeg start header correction\r\n");
if(i <= fileSize){
//header = (SOF2 == NULL) ? (SOF1) : (SOF2);
header = SOF1;
jpeg_debug("header: %x %x %x\r\n", header[0], header[1], header[2]);
header += 3; //length(2) + sampling bit(1)
*header = (height>>8) & 0xFF;
*header++;
*header = height & 0xFF;
*header++;
*header = (width>>8) & 0xFF;
*header++;
*header = width & 0xFF;
}
}
/*************************************************************************************************************************
*函数 : static void JPEG_MemMove(u8* dest, u8* src,u32 count)
*功能 : 由src所指内存区域复制count个字节到dest所指内存区域
*参数 : src: 源地址
* dest: 目标地址
* count: 数据数量
*返回 : 无
*依赖 : 无
*作者 : cp1300@139.com
*时间 : 2013014
*最后修改时间 : 2013114
*说明 : 内存复制,8bit对齐,为了减少外部函数的依赖
*************************************************************************************************************************/
static void JPEG_MemMove(u8* dest, u8* src,u32 count)
{
u32 i;
for(i = 0;i < count;i ++)
{
dest[i] = src[i];
}
}
/*************************************************************************************************************************
*函数 : static void JPEG_WriteYUV(u32 ImageAddr, u16 width, u16 orgwidth, u16 height, u16 orgheight)
*功能 : 重写YUV数据,将数据对齐
*参数 : ImageAddr: 解码后图像地址
* width: 图像对齐后的宽度
* orgwidth: 图像原始宽度
* height: 图像对齐后的高度
* orgheight: 图像原始高度
*返回 : 无
*依赖 : 无
*作者 : cp1300@139.com
*时间 : 20120920
*最后修改时间 : 2010113
*说明 : 无
*************************************************************************************************************************/
static void JPEG_WriteYUV(u32 ImageAddr, u16 width, u16 orgwidth, u16 height, u16 orgheight)
{
u32 src, dst;
u32 i;
u8 *streamPtr;
streamPtr = (u8 *)ImageAddr;
src = 2*width;
dst = 2*orgwidth;
for(i = 1; i < orgheight; i++)
{
JPEG_MemMove(&streamPtr[dst], &streamPtr[src], 2*orgwidth);
src += 2*width;
dst += 2*orgwidth;
}
}
|
评论暂时关闭