S3C6410 裸机硬件JPEG解码

来源:互联网 发布:sql删除一个表的命令 编辑:程序博客网 时间:2024/05/20 11:24

 

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_DBUG0#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)#defineENABLE_IRQ(0xf<<3)//等待超时定义#define WaitTimeOut0xffffff//等待超时计数器//定义最大图像宽高度#define MAX_JPG_WIDTH4096#define MAX_JPG_HEIGHT4096//JPEG寄存器结构定义typedef struct{u32Mode;//模式寄存器u32Status;//状态寄存器u32QTblNo;u32RSTPos;u32Vertical;//垂直分辨率u32Horizontal;//水平分辨率u32DataSize;//压缩数据字节数u32IRQ;//中断设置寄存器u32IRQStatus;//中断状态寄存器0x20u32Reserved0[247];u32QTBL0[64];//0x400u32QTBL1[64];u32QTBL2[64];u32QTBL3[64];u32HDCTBL0[16];//0x800u32HDCTBLG0[12];u32Reserved1[4];u32HACTBL0[16];u32HACTBLG0[162];//0x8c0u32Reserved2[46];u32HDCTBL1[16];//0xc00u32HDCTBLG1[12];u32Reserved3[4];u32HACTBL1[16];u32HACTBLG1[162];//0xcc0u32Reserved4[46];u32ImageAddr0;//目的图像地址1u32ImageAddr1;//目的图像地址2u32JpegAddr0;//源JPEG图像地址1u32JpegAddr1;//源JPEG图像地址2u32Start;//JPEG解码开始u32ReStart;//重新开始JPEG解码u32SofReset;//JPEG复位u32Cntl;//控制寄存器u32COEF1;u32COEF2;u32COEF3;u32Misc;//杂项寄存器u32FramIntv;}JPEG_TypeDef;//定义JPEG文件标记enum{    UNKNOWN,    BASELINE = 0xC0,    EXTENDED_SEQ = 0xC1,    PROGRESSIVE = 0xC2}JPG_SOF_MARKER;//S3C6410 jpeg编解码器基址#define JPEG_BASE0x78800000//寄存器结构指针#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;boolheaderFixed = FALSE;#if JPEG_DBUGconst 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"};#endifif(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);//解码JPEGstatus = 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 pixelif(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);//解码JPEGstatus = 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;    }}


 

/************************************************************************************************************* * 文件名:JpegCodec.H * 功能: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来取消,方便移植。*************************************************************************************************************/#ifndef __JPEGCODEC_H__#define __JPEGCODEC_H__#include "sys_types.h"//数据类型定义//JPEG类型定义typedef enum{TYPE_JPEG_444 = 0, //JPEG 444TYPE_JPEG_422 = 1, //JPEG 422TYPE_JPEG_420 = 2, //JPEG 420TYPE_JPEG_400 = 3, //JPEG 400 (Gray)TYPE_JPEG_411 = 4,//JPEG 411TYPE_JPEG_UNKNOWN = 5//未知} JPEG_TYPE;//JPEG DEC模式typedef enum{DEC_HEADER = 0, //只解码头部信息DEC_BODY = 1, //只解码主体} JPEG_DEC_MODE;//JPEG DEC模式typedef enum{JPEG_OK=0,//正常处理完成JPEG_HEADER_OK=1,//图像大小和取样因素值可读。JPEG_BITSTRE_ERROR=2,//在被压缩的文件上,有语法错误JPEG_WAIT_TIME_OUT=3,//等待超时JPEG_TYPE_ERROR   = 4,//不支持的图像类型,图像类型错误JPEG_SIZE_ERROR   = 5,//图像大小错误,图像分辨率为0,或超出范围JPEG_OTHER_ERROR=6//其它未知错误,一般是地址未16字节对齐} JPEG_ERROR;//JPEG 文件信息typedef struct{u16 Width;//图像宽度u16 Height;//图像高度u32 FileSize;//JPEG图片大小u32 DataSize;//图像解码后数据大小JPEG_TYPE Type;//图像类型定义} JPEG_INFO;//图像压缩质量等级typedef enum{    JPEG_QUALITY_LEVEL_1 = 0, //高质量    JPEG_QUALITY_LEVEL_2 = 1,    JPEG_QUALITY_LEVEL_3 = 2,    JPEG_QUALITY_LEVEL_4 = 3//低质量   }JPEG_QUALITY_TYPE;//相关函数声明void JPEG_Init(void);//JPEG解码初始化void JPEG_ReadClearStatus(u8* Status, u8* IrqStatus);//读取并清除JPEG状态u32 JPEG_GetYUVSize(JPEG_TYPE jpegType,u16 width, u16 height);//获取解码后数据大小JPEG_ERROR JPEG_DecodeOneFrame(u32 JpgAddr, u32 ImageAddr, u32 jpegSize, JPEG_INFO *JpegInfo);//开始解码一帧JPEGJPEG_ERROR JPEG_EncodeOneFrame(u32 JpgAddr, u32 ImageAddr, JPEG_QUALITY_TYPE jpegQuality, JPEG_INFO *JpegInfo);//开始编码一张JPEG#endif // __JPEGCODEC_H__


 

/************************************************************************************************************* * 文件名:jpeg_tables.h * 功能:S3C6410 jpeg编码表 * 作者:cp1300@139.com * 创建时间:2013年01月14日 * 最后修改时间:2013年01月14日 * 详细:直接使用的官方的代码*************************************************************************************************************/#ifndef __JPEG_TABLES_H__#define __JPEG_TABLES_H__const unsigned char QTBL_Luminance[4][64]={    // level 1 - high quality    {        8, 6, 6, 8, 12, 14, 16, 17,        6, 6, 6, 8, 10, 13, 12, 15,        6, 6, 7, 8, 13, 14, 18, 24,        8, 8, 8, 14, 13, 19, 24, 35,        12, 10, 13, 13, 20, 26, 34, 39,        14, 13, 14, 19, 26, 34, 39, 39,        16, 12, 18, 24, 34, 39, 39, 39,        17, 15, 24, 35, 39, 39, 39, 39    },        // level 2    {        12, 8, 8, 12, 17, 21, 24, 23,         8, 9, 9, 11, 15, 19, 18, 23,         8, 9, 10, 12, 19, 20, 27, 36,         12, 11, 12, 21, 20, 28, 36, 53,         17, 15, 19, 20, 30, 39, 51, 59,         21, 19, 20, 28, 39, 51, 59, 59,         24, 18, 27, 36, 51, 59, 59, 59,         23, 23, 36, 53, 59, 59, 59, 59     },    // level 3    {        16, 11, 11, 16, 23, 27, 31, 30,         11, 12, 12, 15, 20, 23, 23, 30,         11, 12, 13, 16, 23, 26, 35, 47,         16, 15, 16, 23, 26, 37, 47, 64,         23, 20, 23, 26, 39, 51, 64, 64,         27, 23, 26, 37, 51, 64, 64, 64,         31, 23, 35, 47, 64, 64, 64, 64,         30, 30, 47, 64, 64, 64, 64, 64     },    // level 4 - low quality    {        20, 16, 25, 39, 50, 46, 62, 68,         16, 18, 23, 38, 38, 53, 65, 68,         25, 23, 31, 38, 53, 65, 68, 68,         39, 38, 38, 53, 65, 68, 68, 68,         50, 38, 53, 65, 68, 68, 68, 68,         46, 53, 65, 68, 68, 68, 68, 68,         62, 65, 68, 68, 68, 68, 68, 68,         68, 68, 68, 68, 68, 68, 68, 68     }};const unsigned char QTBL_Chrominance[4][64]={    // level 1 - high quality    {        9, 8, 9, 11, 14, 17, 19, 24,         8, 10, 9, 11, 14, 13, 17, 22,         9, 9, 13, 14, 13, 15, 23, 26,         11, 11, 14, 14, 15, 20, 26, 33,         14, 14, 13, 15, 20, 24, 33, 39,         17, 13, 15, 20, 24, 32, 39, 39,         19, 17, 23, 26, 33, 39, 39, 39,         24, 22, 26, 33, 39, 39, 39, 39    },    // level 2    {        13, 11, 13, 16, 20, 20, 29, 37,         11, 14, 14, 14, 16, 20, 26, 32,         13, 14, 15, 17, 20, 23, 35, 40,         16, 14, 17, 21, 23, 30, 40, 50,         20, 16, 20, 23, 30, 37, 50, 59,         20, 20, 23, 30, 37, 48, 59, 59,         29, 26, 35, 40, 50, 59, 59, 59,         37, 32, 40, 50, 59, 59, 59, 59     },    // level 3    {        17, 15, 17, 21, 20, 26, 38, 48,         15, 19, 18, 17, 20, 26, 35, 43,         17, 18, 20, 22, 26, 30, 46, 53,         21, 17, 22, 28, 30, 39, 53, 64,         20, 20, 26, 30, 39, 48, 64, 64,         26, 26, 30, 39, 48, 63, 64, 64,         38, 35, 46, 53, 64, 64, 64, 64,         48, 43, 53, 64, 64, 64, 64, 64      },    // level 4 - low quality    {        21, 25, 32, 38, 54, 68, 68, 68,         25, 28, 24, 38, 54, 68, 68, 68,         32, 24, 32, 43, 66, 68, 68, 68,         38, 38, 43, 53, 68, 68, 68, 68,         54, 54, 66, 68, 68, 68, 68, 68,         68, 68, 68, 68, 68, 68, 68, 68,         68, 68, 68, 68, 68, 68, 68, 68,         68, 68, 68, 68, 68, 68, 68, 68      }};const unsigned char QTBL0[64]={#if 1    0x10, 0x0B, 0x0A, 0x10, 0x18, 0x28, 0x33, 0x3D,    0x0C, 0x0C, 0x0E, 0x13, 0x1A, 0x3A, 0x3C, 0x37,    0x0E, 0x0D, 0x10, 0x18, 0x28, 0x39, 0x45, 0x38,    0x0E, 0x11, 0x16, 0x1D, 0x33, 0x57, 0x50, 0x3E,    0x12, 0x16, 0x25, 0x38, 0x44, 0x6D, 0x67, 0x4D,    0x18, 0x23, 0x37, 0x40, 0x51, 0x68, 0x71, 0x5C,    0x31, 0x40, 0x4E, 0x57, 0x67, 0x79, 0x78, 0x65,    0x48, 0x5C, 0x5F, 0x62, 0x70, 0x64, 0x67, 0x63#else    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01#endif};//Added Quantization Tableconst unsigned char std_chrominance_quant_tbl_plus[64]={        0x11, 0x12, 0x18, 0x2F, 0x63, 0x63, 0x63, 0x63,    0x12, 0x15, 0x1A, 0x42, 0x63, 0x63, 0x63, 0x63,    0x18, 0x1A, 0x38, 0x63, 0x63, 0x63, 0x63, 0x63,    0x2F, 0x42, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,    0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,    0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,    0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,    0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63};//Quantization Table0unsigned char std_luminance_quant_tbl[64] ={    1,   1,   2,   1,   1,   2,   2,   2,    2,   3,   2,   2,   3,   3,   6,   4,    3,   3,   3,   3,   7,   5,   8,   4,    6,   8,   8,  10,   9,   8,   7,  11,    8,  10,  14,  13,  11,  10,  10,  12,    10,   8,   8,  11,  16,  12,  12,  13,    15,  15,  15,  15,   9,  11,  16,  17,    15,  14,  17,  13,  14,  14,  14,   1 };//Quantization Table1unsigned char std_chrominance_quant_tbl[64] ={    4,   4,   4,   5,   4,   5,   9,   5,    5,   9,  15,  10,   8,  10,  15,  26,    19,   9,   9,  19,  26,  26,  26,  26,    13,  26,  26,  26,  26,  26,  26,  26,    26,  26,  26,  26,  26,  26,  26,  26,    26,  26,  26,  26,  26,  26,  26,  26,    26,  26,  26,  26,  26,  26,  26,  26,    26,  26,  26,  26,  26,  26,  26,  26};//Huffman Tableunsigned char HDCTBL0[16]  = {0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0};unsigned char HDCTBLG0[12] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb};unsigned char HACTBL0[16]= {0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d};const unsigned char HACTBLG0[162]={    0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,    0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,    0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,    0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,    0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16,    0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,    0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,    0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,    0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,    0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,    0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,    0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,    0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,    0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,    0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,    0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,    0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,    0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,    0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,    0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,    0xf9, 0xfa};//Huffman Table0unsigned char len_dc_luminance[16] ={ 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 };unsigned char val_dc_luminance[12] ={ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };unsigned char len_ac_luminance[16] ={ 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d };unsigned char val_ac_luminance[162] ={    0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,    0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,    0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,    0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,    0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16,    0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,    0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,    0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,    0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,    0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,    0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,    0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,    0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,    0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,    0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,    0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,    0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,    0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,    0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,    0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,    0xf9, 0xfa};//Huffman Table1unsigned char len_dc_chrominance[16] ={ 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 };unsigned char val_dc_chrominance[12] ={ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };unsigned char len_ac_chrominance[16] ={ 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 0x77 };unsigned char val_ac_chrominance[162] ={    0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21,    0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,    0x13, 0x22, 0x32, 0x81, 0x81, 0x08, 0x14, 0x42,    0x91, 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52,    0xf0, 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24,    0x34, 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a,    0x26, 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37,    0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47,    0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57,    0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67,    0x68, 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77,    0x78, 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86,    0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95,    0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4,    0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3,    0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2,    0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca,    0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9,    0xda, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8,    0xe9, 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,    0xf8, 0xf9};#endif//__JPEG_TABLES_H__

 

 

/************************************************************************************************************* * 文件名:sys_types.h * 功能:S3C6410相关数据定义 * 作者:cp1300@139.com * 创建时间:2012年3月4日15:55 * 最后修改时间:2012年3月4日 * 详细:相关数据结构定义*************************************************************************************************************/#ifndef _SYS_TYPES_H_#define _SYS_TYPES_H_typedef signed long long  s64;typedef signed long  s32;typedef signed shorts16;typedef signed char  s8; typedef signed long  long const sc64;  /* Read Only */typedef signed long  const sc32;  /* Read Only */typedef signed short const sc16;  /* Read Only */typedef signed char  const sc8;   /* Read Only */typedef volatile signed long long vs64;typedef volatile signed long  vs32;typedef volatile signed short vs16;typedef volatile signed char  vs8;typedef volatile signed long long  const vsc64;  /* Read Only */typedef volatile signed long  const vsc32;  /* Read Only */typedef volatile signed short const vsc16;  /* Read Only*/typedef volatile signed char  const vsc8;   /* Read Only */typedef unsigned long long u64;typedef unsigned long  u32;typedef unsigned short u16;typedef unsigned char  u8;typedef unsigned long long const uc64;  /* Read Only */typedef unsigned long  const uc32;  /* Read Only */typedef unsigned short const uc16;  /* Read Only */typedef unsigned char  const uc8;   /* Read Only */ typedef volatile unsigned long long vu64;typedef volatile unsigned long  vu32;typedef volatile unsigned short vu16;typedef volatile unsigned char  vu8;typedef volatile unsigned long long const vuc64;  /* Read Only */ typedef volatile unsigned long  const vuc32;  /* Read Only */typedef volatile unsigned short const vuc16;  /* Read Only*/typedef volatile unsigned char  const vuc8;   /* Read Only */ typedef enum {FALSE= 0, TRUE = !FALSE} bool; typedef enum {RESET = 0, SET = !RESET} FlagStatus, ITStatus;typedef enum {DISABLE = 0, ENABLE = !DISABLE} FunctionalState;#define IS_FUNCTIONAL_STATE(STATE) (((STATE) == DISABLE) || ((STATE) == ENABLE))typedef enum {ERROR = 0, SUCCESS = !ERROR} ErrorStatus;#define U8_MAX     ((u8)255)#define S8_MAX     ((s8)127)#define S8_MIN     ((s8)-128)#define U16_MAX    ((u16)65535u)#define S16_MAX    ((s16)32767)#define S16_MIN    ((s16)-32768)#define U32_MAX    ((u32)4294967295uL)#define S32_MAX    ((s32)2147483647)#define S32_MIN    ((s32)-2147483648)#endif

 

 

 

主函数的部分代码

/**************************************************************************************************************************函数        :static PIC_ERROR OpenPictureFile(const char *FileName,u8 *buff,u32 FileMaxSize)*功能        :打开一张,并将数据读取到内存*参数        :FileName:文件名,路径指针;buff:读取缓冲区;FileMaxSize:文件最大限制*返回        :PIC_ERROR*依赖     : FATFS文件系统支持*作者        :cp1300@139.com*时间     :20121207*最后修改时间:20121209*说明     :调用FATFS打开图片文件*************************************************************************************************************************/int OpenPictureFile(const char *FileName,u8 *buff,u32 FileMaxSize){FIL file;UINT cnt;int status;int error = 0;status = f_open(&file,FileName,FA_READ);//只读方式打开文件if(status != FR_OK)//打开文件错误{uart_printf("open \"%s\" error!\r\n",FileName);error = 1;}else{//获取文件大小uart_printf("file size : %dB\r\n",file.fsize);//输出文件大小if(file.fsize > FileMaxSize){uart_printf("file size > %d\r\n",FileMaxSize);error = 2;}else{status = f_read(&file,buff,file.fsize,&cnt);//读取文件uart_printf("Read File Num=%d\r\n",cnt);if(cnt == file.fsize)//判断文件是否读取完毕{uart_printf("read file end!\r\n");error =  0;}else{uart_printf("read file error!\r\n");error = 3;}}}f_close(&file);return error;}void YUV422ToRGB565(u8 *YUVBuff,u16 width,u16 height){u16 x,y;u32 RGBdata;u32 cnt = 0;u8 Y,U = 0,V = 0;int R,G,B;for(y = 0;y < height;y ++){ for(x = 0;x < width;x ++ ){ Y = YUVBuff[cnt << 1];if((cnt % 2) == 0){U = YUVBuff[(cnt << 1) + 1];V = YUVBuff[(cnt << 1) + 3];} R = Y + (1.370705 * (V - 128));        G = Y - (0.698001 * (V - 128)) - (0.337633 * (U-128));        B = Y + (1.732446 * (U - 128));        R = (R > 255) ? 255 : ((R < 0) ? 0 : R);        G = (G > 255) ? 255 : ((G < 0) ? 0 : G);        B = (B > 255) ? 255 : ((B < 0) ? 0 : B);//RGBdata = (u32)(R << 16) | (G << 8) | B;        R >>= 3;        G >>= 2;B >>= 3;        RGBdata = (R << 11) + (G << 5) + B;        LCD_DrawPoint(x,y,(u16)RGBdata);//LCD_DrawPoint(x,y,RGB888toRGB565(RGBdata));cnt ++;}}}u8 buff[10*1024*1024];u8 image[10*1024*1024];//主函数int main(void){OS_CPU_SR  cpu_sr;int result;JPEG_INFO JpegInfo;u32 p;u32 i;UART0_Init(DISABLE,115200);//初始化串口,失能中断接收,波特率115200LCD_Init();//初始化LCDLED_Init();//初始化LEDRunTimeInit();JPEG_Init();result = Explorer_Init();//初始化资源管理器if(result == 0){lcd_printf("Disk Init OK!\n");}else{lcd_printf("Disk Init Error(%d)!\n",result);}p = (u32)buff;if((u32)buff % 16){p = (p / 16 + 1) * 16;}OpenPictureFile("0:/system/ui/ico/设置.jpg",(u8 *)p,10*1024*1024);result = JPEG_DecodeOneFrame(p,(u32)image,31654, &JpegInfo);uart_printf("decode jpeg file %d\r\n",result);if(result == 0){YUV422ToRGB565(image,JpegInfo.Width,JpegInfo.Height);}




 

 


附:任意文件转C数组工具:http://download.csdn.net/detail/cp1300/4588229