//解码文件名为filename的jpeg/jpg文件 u8 jpg_decode(const u8 *filename) { u8 res=0; u16 br; #if JPEG_USE_MALLOC == 1//使用malloc res=jpeg_mallocall(); #endif if(res==0)//内存申请OK { //得到JPEG/JPG图片的开始信息 res=f_open(f_jpeg,(const TCHAR*)filename,FA_READ);//打开文件 if(res==0) { //开始时读入1024个字节到缓存里面.方便后面提取JPEG解码的信息 f_read(f_jpeg,jpg_buffer,1024,(UINT*)&br); jpeg_inittable();//初始化各个数据表 res=jpeg_inittag(); if(res==0) { if((SampRate_Y_H!=0)&&(SampRate_Y_V!=0)) { ai_draw_init(); //初始化picinfo.Div_Fac,启动智能画图 res=jpeg_decode(); //解码JPEG开始 }else res=0XFD; //采样率错误 }else res=0XFE; //初始化表头不成功 f_close(f_jpeg); } } #if JPEG_USE_MALLOC == 1//使用malloc jpeg_freeall(); //释放内存 #endif return res; }
//标准的bmp解码,解码filename这个BMP文件 //速度比较慢.主要 //filename:包含路径的文件名 //返回值:0,成功; // 其他,错误码. u8 stdbmp_decode(const u8 *filename) { FIL* f_bmp; u16 br; u16 count; u8 rgb ,color_byte; u16 x ,y,color; u16 countpix=0;//记录像素 //x,y的实际坐标 u16 realx=0; u16 realy=0; u8 yok=1; u8 res; u8 *databuf; //数据读取存放地址 u16 readlen=BMP_DBUF_SIZE;//一次从SD卡读取的字节数长度 u8 *bmpbuf; //数据解码地址 u8 biCompression=0; //记录压缩方式 u16 rowlen; //水平方向字节数 BITMAPINFO *pbmp; //临时指针 #if BMP_USE_MALLOC == 1 //使用malloc databuf=(u8*)pic_memalloc(readlen); //开辟readlen字节的内存区域 if(databuf==NULL)return PIC_MEM_ERR; //内存申请失败. f_bmp=(FIL *)pic_memalloc(sizeof(FIL)); //开辟FIL字节的内存区域 if(f_bmp==NULL) //内存申请失败. { pic_memfree(databuf); return PIC_MEM_ERR; } #else //不使用malloc databuf=bmpreadbuf; f_bmp=&f_bfile; #endif res=f_open(f_bmp,(const TCHAR*)filename,FA_READ);//打开文件 if(res==0)//打开成功. { f_read(f_bmp,databuf,readlen,(UINT*)&br); //读出readlen个字节 pbmp=(BITMAPINFO*)databuf; //得到BMP的头部信息 count=pbmp->bmfHeader.bfOffBits; //数据偏移,得到数据段的开始地址 color_byte=pbmp->bmiHeader.biBitCount/8; //彩色位 16/24/32 biCompression=pbmp->bmiHeader.biCompression;//压缩方式 picinfo.ImgHeight=pbmp->bmiHeader.biHeight; //得到图片高度 picinfo.ImgWidth=pbmp->bmiHeader.biWidth; //得到图片宽度 ai_draw_init();//初始化智能画图 //水平像素必须是4的倍数!! if((picinfo.ImgWidth*color_byte)%4)rowlen=((picinfo.ImgWidth*color_byte)/4+1)*4; else rowlen=picinfo.ImgWidth*color_byte; //开始解码BMP color=0;//颜色清空 x=0 ; y=picinfo.ImgHeight; rgb=0; //对于尺寸小于等于设定尺寸的图片,进行快速解码 realy=(y*picinfo.Div_Fac)>>13; bmpbuf=databuf; while(1) { while(count<readlen) //读取一簇1024扇区 (SectorsPerClust 每簇扇区数) { if(color_byte==3) //24位颜色图 { switch (rgb) { case 0: color=bmpbuf[count]>>3; //B break ; case 1: color+=((u16)bmpbuf[count]<<3)&0X07E0;//G break; case 2 : color+=((u16)bmpbuf[count]<<8)&0XF800;//R break ; } }else if(color_byte==2) //16位颜色图 { switch(rgb) { case 0 : if(biCompression==BI_RGB)//RGB:5,5,5 { color=((u16)bmpbuf[count]&0X1F); //R color+=(((u16)bmpbuf[count])&0XE0)<<1; //G }else //RGB:5,6,5 { color=bmpbuf[count]; //G,B } break ; case 1 : if(biCompression==BI_RGB)//RGB:5,5,5 { color+=(u16)bmpbuf[count]<<9; //R,G }else //RGB:5,6,5 { color+=(u16)bmpbuf[count]<<8; //R,G } break ; } }else if(color_byte==4)//32位颜色图 { switch (rgb) { case 0: color=bmpbuf[count]>>3; //B break ; case 1: color+=((u16)bmpbuf[count]<<3)&0X07E0;//G break; case 2 : color+=((u16)bmpbuf[count]<<8)&0XF800;//R break ; case 3 : //alphabend=bmpbuf[count];//不读取 ALPHA通道 break ; } }else if(color_byte==1)//8位色,暂时不支持,需要用到颜色表. { } rgb++; count++ ; if(rgb==color_byte) //水平方向读取到1像素数数据后显示 { if(x<picinfo.ImgWidth) { realx=(x*picinfo.Div_Fac)>>13;//x轴实际值 if(is_element_ok(realx,realy,1)&&yok)//符合条件 { pic_phy.draw_point(realx+picinfo.S_XOFF,realy+picinfo.S_YOFF-1,color);//显示图片 //POINT_COLOR=color; //LCD_DrawPoint(realx+picinfo.S_XOFF,realy+picinfo.S_YOFF); //SRAMLCD.Draw_Point(realx+picinfo.S_XOFF,realy+picinfo.S_YOFF,color); } } x++;//x轴增加一个像素 color=0x00; rgb=0; }