Files
player/Project/Src/JPEG/picdeco.c
2025-07-05 19:47:28 +08:00

218 lines
4.6 KiB
C

#include "main.h"
#include "picdeco.h"
FIL File_JPEG;
JDEC JPEG_Dev;
FIL *f_jpeg = &File_JPEG;
JDEC *jpeg_dev = &JPEG_Dev;
__attribute__((aligned(4))) u8 jpg_buffer[JPEG_BufferSize];
static u16 JPEG_X = 0; //图片显示的起始坐标
static u16 JPEG_Y = 0; //图片显示的起始坐标
//从文件系统里读取数据
static UINT In_Func (JDEC* jdec,BYTE* buff,UINT ndata)
{
UINT rb;
FIL *dev=(FIL*)jdec->device;
if(buff)
{
f_read(dev,buff,ndata,&rb);
return rb;
}
else return (f_lseek(dev,f_tell(dev)+ndata)==FR_OK)?ndata:0;
}
//#define COLOR565TO888(color) (((color&0xf800)<<8)|(color&0x07e0)<<5|((color&0x001f)<<3))
//直接把图像输出到屏幕
static UINT Out_Func (JDEC* jdec,void* bitmap,JRECT* rect)
{
u16 m,n;
u16 x = rect->left,y = 0; //实际要显示的X、Y坐标
u16 *PointColor = bitmap; //像素点的颜色
u16 JPEG_Width = rect->right-rect->left+1;
u16 JPEG_Height = rect->bottom-rect->top+1;
for(m=0;m<JPEG_Height;m++)
{
y=(8193*(rect->top+m))>>13; //实际显示的y坐标
for(n=0;n<JPEG_Width;n++)
{
x=(8193*(rect->left+n))>>13; //实际显示的x坐标
//extern u32* LCD_ADDR;
if (x<480&y<272)
{
int point=(480*272-1)-((y+JPEG_Y)*480+(JPEG_X+x));
//if ((point>=0)&&(point<480*272))
//LCD_ADDR[point]=COLOR565TO888((*PointColor));
}
PointColor++;
}
}
return 0; //成功返回0
}
//解码并把图像输出到屏幕
u8 JPEG_Show(const u8 *filename,u16 x,u16 y)
{
u8 JPEG_Res; // 文件操作结果
JPEG_X = x;
JPEG_Y = y;
JPEG_Res = f_open(f_jpeg,(const TCHAR*)filename,FA_READ);//打开文件
if( JPEG_Res == FR_OK ) //读取JPEG文件成功
{
JPEG_Res = jd_prepare(jpeg_dev,In_Func,jpg_buffer,JPEG_BufferSize,f_jpeg); //准备解码
if( JPEG_Res == JDR_OK ) //操作成功成功
{
JPEG_Res=jd_decomp(jpeg_dev,Out_Func,0); //进行JPEG的解码并显示
}
}
f_close(f_jpeg); //关闭文件
return JPEG_Res;
}
BITMAP_Struct *g_BITMAP_struct=0;
//图像缓存到内存
static UINT Out_Func2 (JDEC* jdec,void* bitmap,JRECT* rect)
{
u16 m,n;
u16 x = rect->left,y = 0; //实际要显示的X、Y坐标
u16 *PointColor = bitmap; //像素点的颜色
u16 JPEG_Width = rect->right-rect->left+1;
u16 JPEG_Height = rect->bottom-rect->top+1;
u16 *buff=g_BITMAP_struct->buff;
int buff_size=g_BITMAP_struct->x_size*g_BITMAP_struct->y_size-1;
for(m=0;m<JPEG_Height;m++)
{
y=(8193*(rect->top+m))>>13; //实际显示的y坐标
for(n=0;n<JPEG_Width;n++)
{
int temp=0;
x=(8193*(rect->left+n))>>13; //实际显示的x坐标
//temp=buff_size-(y*g_BITMAP_struct->x_size+x);
temp=(y*g_BITMAP_struct->x_size+x);
buff[temp]=*PointColor;
PointColor++;
}
}
return 0; //成功返回0
}
//解码并把图像存储在内存
u8 JPEG_Decode(const u8 *filename,BITMAP_Struct *bitmap)
{
u8 JPEG_Res; // 文件操作结果
g_BITMAP_struct=bitmap;
JPEG_Res = f_open(f_jpeg,(const TCHAR*)filename,FA_READ);//打开文件
if( JPEG_Res == FR_OK ) //读取JPEG文件成功
{
JPEG_Res = jd_prepare(jpeg_dev,In_Func,jpg_buffer,JPEG_BufferSize,f_jpeg); //准备解码
if( JPEG_Res == JDR_OK ) //操作成功成功
{
g_BITMAP_struct->x_size=jpeg_dev->width;
g_BITMAP_struct->y_size=jpeg_dev->height;
g_BITMAP_struct->buff=mymalloc_exm(jpeg_dev->width*jpeg_dev->height*2);
if (g_BITMAP_struct->buff!=0)
{
JPEG_Res=jd_decomp(jpeg_dev,Out_Func2,0); //进行JPEG的解码并显示
}
else
{
JPEG_Res=(u8)-1;
}
}
}
f_close(f_jpeg); //关闭文件
return JPEG_Res;
}
struct data_struct
{
u8 *data;
u32 offset;
u32 size;
};
//从内存中读取数据
static UINT In_Func_Ram (JDEC* jdec,BYTE* buff,UINT ndata)
{
u32 rb;
struct data_struct *data=(struct data_struct *)jdec->device;
if (data->size>data->offset+ndata)
{
rb=ndata;
}
else
{
rb=data->size-(data->offset);
}
if(buff)
{
mymemcpy (buff,&data->data[data->offset],rb);
data->offset+=rb;
return rb;
}
else
{
return rb;
}
}
//解码存储在ram中的jpeg数据
u8 JPEG_Decode_Ram(u8 *data,u32 size,BITMAP_Struct *bitmap)
{
u8 JPEG_Res; // 文件操作结果
g_BITMAP_struct=bitmap;
if( data ) //读取JPEG文件成功
{
struct data_struct data_struct={0};
data_struct.data=data;
data_struct.size=size;
JPEG_Res = jd_prepare(jpeg_dev,In_Func_Ram,jpg_buffer,JPEG_BufferSize,&data_struct); //准备解码
if( JPEG_Res == JDR_OK ) //操作成功成功
{
g_BITMAP_struct->x_size=jpeg_dev->width;
g_BITMAP_struct->y_size=jpeg_dev->height;
g_BITMAP_struct->buff=mymalloc(jpeg_dev->width*jpeg_dev->height*2);
if (g_BITMAP_struct->buff!=0)
{
JPEG_Res=jd_decomp(jpeg_dev,Out_Func2,0); //进行JPEG的解码并显示
}
else
{
JPEG_Res=(u8)-1;
}
}
}
return JPEG_Res;
}