Files
player/Project/Src/MyWinApp/mywin_user_photo.c

573 lines
12 KiB
C
Raw Normal View History

2025-06-27 00:32:57 +08:00
#include "mywin_inc.h"
#include "mywin_user_photo.h"
#include "ff.h"
#include "picdeco.h"
#include "bmp.h"
#include "png.h"
#include <zlib.h>
#include "system_file.h"
#define WIN_PHOTO_TYPE "WIN_PhotoStruct"
static const char *g_popup_itmes[]=
{
2025-07-05 19:47:28 +08:00
"<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>",
"ת<EFBFBD><EFBFBD>Ϊ<EFBFBD>Ҷ<EFBFBD>",
"ת<EFBFBD><EFBFBD>Ϊλͼ",
"<EFBFBD>˳<EFBFBD>",
2025-06-27 00:32:57 +08:00
};
WIN_PhotoStruct *WIN_CreatPhoto (WIN_WindowStruct *base,
void (*msgLoop)(struct _WIN_WindowStruct *win,WIN_MsgStruct *msg),
int x,int y,int x_size,int y_size)
{
2025-07-05 19:47:28 +08:00
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣѭ<CFA2><D1AD>
2025-06-27 00:32:57 +08:00
if (msgLoop==0)
{
msgLoop=(void (*)(struct _WIN_WindowStruct *win,WIN_MsgStruct *msg))PHOTO_defaultMsgLoop;
}
WIN_PhotoStruct *ret=mymalloc (sizeof ( WIN_PhotoStruct));
2025-07-05 19:47:28 +08:00
//<2F><><EFBFBD>ø<EFBFBD><C3B8><EFBFBD><EFBFBD>Ĺ<EFBFBD><C4B9><EFBFBD><ECBAAF>
2025-06-27 00:32:57 +08:00
if (ret)
{
mymemset (ret,0,sizeof ( WIN_PhotoStruct));
if (0==WIN_CreatWindowExt((WIN_WindowStruct *)ret,base,msgLoop,x,y,x_size,y_size))
{
2025-07-05 19:47:28 +08:00
//<2F><><EFBFBD><EFBFBD>ʧ<EFBFBD><CAA7>
2025-06-27 00:32:57 +08:00
myfree (ret);
ret=0;
}
else
{
2025-07-05 19:47:28 +08:00
//<2F><><EFBFBD><EFBFBD>
2025-06-27 00:32:57 +08:00
((WIN_WindowStruct *)ret)->deleteWindow=(void (*)(struct _WIN_WindowStruct *win))WIN_DeletePhoto;
((WIN_WindowStruct *)ret)->winType=WIN_PHOTO_TYPE;
((WIN_WindowStruct *)ret)->intercept=1;
((WIN_WindowStruct *)ret)->bkcolor=0x808080;
((WIN_WindowStruct *)ret)->color=0xffffff;
}
}
return ret;
}
void WIN_DeletePhoto (WIN_PhotoStruct *photo)
{
if (photo->memData)
{
myfree (photo->memData);
}
if (photo->memDataGray)
{
myfree (photo->memDataGray);
}
if (photo->memDataBit)
{
myfree (photo->memDataBit);
}
2025-07-05 19:47:28 +08:00
//<2F><><EFBFBD>ø<EFBFBD><C3B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ٺ<EFBFBD><D9BA><EFBFBD>
2025-06-27 00:32:57 +08:00
WIN_DeleteWindow ( (WIN_WindowStruct *)photo);
}
2025-07-05 19:47:28 +08:00
//<2F><><EFBFBD><EFBFBD>ͼƬ
2025-06-27 00:32:57 +08:00
void PHOTO_SetPic (WIN_PhotoStruct *photo,WIN_PicStruct *pic)
{
mymemcpy(&((WIN_WindowStruct *)photo)->pic,pic,sizeof(WIN_PicStruct));
mymemcpy(&photo->pic,pic,sizeof(WIN_PicStruct));
}
static int go_trsGray (void *ptr)
{
WIN_PhotoStruct *photo =ptr;
u16 *img=photo->memDataGray;
for (int i=0;i<photo->pic.xsize*photo->pic.ysize;i++)
{
img[i]=RGB2GRAY (photo->pic.data[i]);
img[i]=GRAY2RGB (img[i]);
}
photo->grayTrs=1;
return 0;
}
2025-07-05 19:47:28 +08:00
//ת<><D7AA>Ϊ<EFBFBD>Ҷ<EFBFBD>ͼ
2025-06-27 00:32:57 +08:00
void PHOTO_TransforGray (WIN_PhotoStruct *photo)
{
if (photo->memDataGray==0)
{
photo->memDataGray=mymalloc (photo->pic.xsize*photo->pic.ysize*2);
}
if ((photo->memDataGray)&&(photo->grayTrs==0))
{
2025-07-05 19:47:28 +08:00
WORKING_DoWork ((WIN_WindowStruct *)photo,"<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɻҶ<EFBFBD>ͼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>",go_trsGray,photo);
2025-06-27 00:32:57 +08:00
}
if (photo->grayTrs)
{
if (photo->pic.data!=photo->memDataGray)
photo->pic.data=photo->memDataGray;
else photo->pic.data=photo->memData;
}
}
static u16 getBit (WIN_PicStruct *pic,int x,int y)
{
if ((x<0||x>=pic->xsize)||(y<0||y>=pic->ysize))
return 0;
else
return pic->data[y*pic->xsize+x]&0x1f;
}
static u16 setBit (WIN_PicStruct *pic,int x,int y,int color)
{
if ((x<0||x>=pic->xsize)||(y<0||y>=pic->ysize))
return 0;
else
{
if (color>0x1f)
return pic->data[y*pic->xsize+x]=0x1f;
else if (color<0)
return pic->data[y*pic->xsize+x]=0;
else
return pic->data[y*pic->xsize+x]=color;
}
}
static u16 getBitRand (WIN_PicStruct *pic,int lev,int x,int y)
{
if ((getBit(pic,x,y)&0x1f)>lev)
return 0x1f;
else
return 0;
}
static int do_work (void *ptr)
{
WIN_PhotoStruct *photo=ptr;
if (photo->memDataBit)
{
u16 *ptr=photo->memDataBit;
u16 *src=photo->memDataGray;
long lev=0;
for (int i=0;i<photo->pic.xsize*photo->pic.ysize;i++)
{
ptr[i]=0x1f&src[i];
lev+=ptr[i];
}
lev/=photo->pic.xsize*photo->pic.ysize;
photo->pic.data=ptr;
for (int y=0;y<photo->pic.ysize;y++)
{
for (int x=0;x<photo->pic.xsize;x++)
{
u16 color_old=ptr[y*photo->pic.xsize+x];
ptr[y*photo->pic.xsize+x]=getBitRand(&photo->pic,lev,x,y);
int quant_error=color_old-ptr[y*photo->pic.xsize+x];
setBit (&photo->pic,x+1,y, getBit(&photo->pic,x+1,y)+quant_error *7/16);
setBit (&photo->pic,x-1,y+1, getBit(&photo->pic,x-1,y+1)+quant_error *3/16);
setBit (&photo->pic,x,y+1, getBit(&photo->pic,x,y+1)+quant_error *5/16);
setBit (&photo->pic,x+1,y+1, getBit(&photo->pic,x+1,y+1)+quant_error *1/16);
if (ptr[y*photo->pic.xsize+x]) ptr[y*photo->pic.xsize+x]=0xffff;
}
}
photo->pic.data=photo->memData;
photo->bitTrs=1;
}
return 0;
}
2025-07-05 19:47:28 +08:00
//ת<><D7AA>Ϊλͼ
2025-06-27 00:32:57 +08:00
int PHOTO_TransforBit (WIN_PhotoStruct *photo)
{
if (photo->grayTrs)
{
if (photo->memDataBit==0)
{
photo->memDataBit=mymalloc (photo->pic.xsize*photo->pic.ysize*2);
2025-07-05 19:47:28 +08:00
WORKING_DoWork ((WIN_WindowStruct *)photo,"<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λͼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>",do_work,photo);
2025-06-27 00:32:57 +08:00
}
}
if (photo->bitTrs)
{
if (photo->pic.data!=photo->memDataBit)
photo->pic.data=photo->memDataBit;
else photo->pic.data=photo->memData;
}
return 0;
}
2025-07-05 19:47:28 +08:00
//<2F><>Ϣ<EFBFBD><CFA2><EFBFBD>Ļ<EFBFBD><C4BB>ƺ<EFBFBD><C6BA><EFBFBD>
2025-06-27 00:32:57 +08:00
void PHOTO_DefaultPaint (WIN_PhotoStruct *photo)
{
WIN_WindowStruct *win=(WIN_WindowStruct *)photo;
WIN_PicStruct *pic=&win->pic;
int xsize=win->x_size;
int ysize=win->y_size;
if(pic->format==PIC_FORMAT_RGB565)
WIN_FillRect (0,0,xsize,ysize,pic->data,0,0,pic->xsize,pic->ysize);
else if(pic->format==PIC_FORMAT_ARGB8888)
WIN_FillRectAlpha (0,0,xsize,ysize,pic->data,0,0,pic->xsize,pic->ysize);
}
static void PHOTO_Enter (WIN_PhotoStruct *photo,int x,int y)
{
int index=POPUP_SelectItem ((WIN_WindowStruct *)photo,(char **)g_popup_itmes,4,x,y);
if (index==0)
{
2025-07-05 19:47:28 +08:00
//<2F><><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD>
2025-06-27 00:32:57 +08:00
WIN_PicStruct pic={0};
WIN_PicStruct *win_pic=&((WIN_WindowStruct *)photo)->pic;
WIN_WindowStruct *home=WIN_GetWinByTitle(0,"home");
if(home)
{
pic.data=home->pic.data;
pic.xsize=home->pic.xsize;
pic.ysize=home->pic.ysize;
int xsize=pic.xsize;int ysize=pic.ysize;
if (xsize>win_pic->xsize) xsize=win_pic->xsize;
if (ysize>win_pic->ysize) ysize=win_pic->ysize;
for (int i=0;i<ysize;i++)
{
for (int j=0;j<xsize;j++)
{
pic.data[i*pic.xsize+j]=win_pic->data[i*win_pic->xsize+j];
}
}
}
}
else if (index==1)
{
2025-07-05 19:47:28 +08:00
//ת<><D7AA>Ϊ<EFBFBD>Ҷ<EFBFBD>ͼ
2025-06-27 00:32:57 +08:00
PHOTO_TransforGray (photo);
((WIN_WindowStruct *)photo)->pic.data=photo->pic.data+photo->x_off+photo->y_off*photo->pic.xsize;
((WIN_WindowStruct *)photo)->pic.ysize=photo->pic.ysize-photo->y_off;
WIN_SetInvalid ((WIN_WindowStruct *)photo);
}
else if (index==2)
{
2025-07-05 19:47:28 +08:00
//ת<><D7AA>Ϊλͼ
2025-06-27 00:32:57 +08:00
PHOTO_TransforBit (photo);
((WIN_WindowStruct *)photo)->pic.data=photo->pic.data+photo->x_off+photo->y_off*photo->pic.xsize;
((WIN_WindowStruct *)photo)->pic.ysize=photo->pic.ysize-photo->y_off;
WIN_SetInvalid ((WIN_WindowStruct *)photo);
}
else if (index==3)
{
2025-07-05 19:47:28 +08:00
//<2F>˳<EFBFBD>
2025-06-27 00:32:57 +08:00
((WIN_WindowStruct *)photo)->deleteWindow((WIN_WindowStruct *)photo);
}
}
2025-07-05 19:47:28 +08:00
//<2F><>Ϣ<EFBFBD><CFA2><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><CFA2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
2025-06-27 00:32:57 +08:00
void PHOTO_defaultMsgLoop (WIN_PhotoStruct *photo,WIN_MsgStruct *msg)
{
WIN_MoveStruct *m=0;
WIN_KeyStruct *k=0;
switch (msg->msg)
{
case WIN_MSG_PAINT:
PHOTO_DefaultPaint(photo);
break;
case WIN_MSG_KEY:
k=msg->data.p;
if (k->shortPress&KEY_VALUE_HOME)
((WIN_WindowStruct *)photo)->deleteWindow((WIN_WindowStruct *)photo);
else if (k->shortPress&KEY_VALUE_ENTER)
{
PHOTO_Enter(photo,100,100);
}
break;
case WIN_MSG_MOVE:
m=msg->data.p;
switch (m->moveType)
{
case MOVE_DATA_MOVED:
2025-07-05 19:47:28 +08:00
//<2F>ȴ<EFBFBD><C8B4>ϴε<CFB4><CEB5><EFBFBD>ʾˢ<CABE><CBA2>
2025-06-27 00:32:57 +08:00
//while (LCD_GetLayerUpdataStat()==0){}
photo->x_off-=m->x_move;
photo->y_off-=m->y_move;
if (photo->x_off<0) photo->x_off=0;
if (photo->y_off<0) photo->y_off=0;
if (photo->pic.xsize>((WIN_WindowStruct *)photo)->x_size)
{
if (photo->x_off>photo->pic.xsize-((WIN_WindowStruct *)photo)->x_size)
photo->x_off=photo->pic.xsize-((WIN_WindowStruct *)photo)->x_size;
}
else photo->x_off=0;
if (photo->pic.ysize>((WIN_WindowStruct *)photo)->y_size)
{
if (photo->y_off>photo->pic.ysize-((WIN_WindowStruct *)photo)->y_size)
photo->y_off=photo->pic.ysize-((WIN_WindowStruct *)photo)->y_size;
}
else photo->y_off=0;
((WIN_WindowStruct *)photo)->pic.data=photo->pic.data+photo->x_off+photo->y_off*photo->pic.xsize;
((WIN_WindowStruct *)photo)->pic.ysize=photo->pic.ysize-photo->y_off;
WIN_SetInvalid ((WIN_WindowStruct *)photo);
break;
case MOVE_DATA_LONG:
PHOTO_Enter(photo,m->x_move,m->y_move);
break;
default:
WIN_DefaultMsgLoop((WIN_WindowStruct *)photo,msg);
break;
}
break;
default:
WIN_DefaultMsgLoop((WIN_WindowStruct *)photo,msg);
break;
}
}
typedef struct
{
u8 *name;
BITMAP_Struct *bitmap;
}decode_jpg_struct;
2025-07-05 19:47:28 +08:00
//ͼƬ<CDBC><C6AC><EFBFBD><EFBFBD><EBB9A4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
2025-06-27 00:32:57 +08:00
static int decode_jpg ( void *ptr)
{
decode_jpg_struct *p=ptr;
return JPEG_Decode (p->name,p->bitmap);
}
typedef struct
{
u8 *name;
BMP_DecodeStruct *bmp;
}decode_bmp_struct;
static int decode_bmp (void *ptr)
{
decode_bmp_struct *p=ptr;
return BMP_Decode (p->name,p->bmp);
}
typedef struct
{
char *name;
WIN_PicStruct *pic;
}decode_png_struct;
2025-07-05 19:47:28 +08:00
//<2F><><EFBFBD><EFBFBD>pngͼƬ<CDBC><C6AC><EFBFBD>ɹ<EFBFBD><C9B9><EFBFBD><EFBFBD><EFBFBD>1<EFBFBD><31>ʧ<EFBFBD>ܷ<EFBFBD><DCB7><EFBFBD>0
2025-06-27 00:32:57 +08:00
static int decode_png(void *ptr)
{
decode_png_struct *p=ptr;
WIN_PicStruct *pic=p->pic;
char *name=p->name;
int png_err=0;
png_image image; /* The control structure used by libpng */
/* Initialize the 'png_image' structure. */
memset(&image, 0, (sizeof image));
image.version = PNG_IMAGE_VERSION;
/* The first argument is the file to read: */
if (png_image_begin_read_from_file(&image, name) != 0)
{
image.format = PNG_FORMAT_BGRA;
pic->data = mymalloc(PNG_IMAGE_SIZE(image));
pic->format=PIC_FORMAT_ARGB8888;
pic->xsize=image.width;
pic->ysize=image.height;
if (
png_err=png_image_finish_read(&image, NULL/*background*/, pic->data,
0/*row_stride*/, NULL/*colormap*/),png_err != 0)
{
return 1;
}
else
{
myfree(pic->data);
return 0;
}
}
return 0;
}
2025-07-05 19:47:28 +08:00
//<2F><>ʾ<EFBFBD><CABE>Ƭ
2025-06-27 00:32:57 +08:00
int PHOTO_ShowPhoto (WIN_WindowStruct *base,char *name)
{
2025-07-05 19:47:28 +08:00
//<2F><><EFBFBD><EFBFBD>ͼƬ
2025-06-27 00:32:57 +08:00
BITMAP_Struct bitmap={0};
WIN_PicStruct pic={0};
u8 ret=0;
2025-07-05 19:47:28 +08:00
//<2F>ж<EFBFBD>ͼƬ<CDBC><C6AC>ʽ
2025-06-27 00:32:57 +08:00
int str_len=strlen(name);
char *p_str=&name[str_len-4];
2025-07-05 19:47:28 +08:00
//<2F><><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>ʾ<EFBFBD><CABE>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
2025-06-27 00:32:57 +08:00
if (strcmp (p_str,".jpg")==0)
{
decode_jpg_struct dec={0};
dec.bitmap=&bitmap;dec.name=(u8*)name;
2025-07-05 19:47:28 +08:00
ret=WORKING_DoWork (base,"JPG<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>С<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>",decode_jpg,&dec);
2025-06-27 00:32:57 +08:00
if (ret==0)
{
pic.data=bitmap.buff;
pic.xsize=bitmap.x_size;
pic.ysize=bitmap.y_size;
}else return -1;
}
else if (strcmp (p_str,".bmp")==0)
{
decode_bmp_struct dec={0};
dec.name=(u8 *)name;
2025-07-05 19:47:28 +08:00
dec.bmp=(BMP_DecodeStruct *)&bitmap;//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E1B9B9><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD>ģ<EFBFBD>ֱ<EFBFBD><D6B1>ǿ<EFBFBD><C7BF>ת<EFBFBD><D7AA>
ret=WORKING_DoWork (base,"BMP<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>С<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>",decode_bmp,&dec);
2025-06-27 00:32:57 +08:00
if (ret==0)
{
pic.data=bitmap.buff;
pic.xsize=bitmap.x_size;
pic.ysize=bitmap.y_size;
}else return -1;
}
else if(strcmp (p_str,".png")==0)
{
decode_png_struct dec={0};
dec.name=name;
dec.pic=&pic;
2025-07-05 19:47:28 +08:00
ret=WORKING_DoWork (base,"PNG<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>С<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>",decode_png,&dec);
2025-06-27 00:32:57 +08:00
if(ret==0)
return -1;
}
WIN_PhotoStruct *photo=0;
int x,y,xsize,ysize;
if (base)
{
//WIN_GetWinPosOnLcd (base,&x,&y,&xsize,&ysize);
x=0;y=0;xsize=base->x_size;ysize=base->y_size;
}
else
{
x=0;y=0;xsize=WIN_GetWinStruct()->lcd->getLcdSizeX();ysize=WIN_GetWinStruct()->lcd->getLcdSizeY();
}
if (pic.xsize<xsize) {x+=(xsize-pic.xsize)/2;xsize=pic.xsize;}
if (pic.ysize<ysize) {y+=(ysize-pic.ysize)/2;ysize=pic.ysize;}
//photo=WIN_CreatPhoto (0,0,x,y,xsize,ysize);
photo=WIN_CreatPhoto (base,0,x,y,xsize,ysize);
PHOTO_SetPic (photo,&pic);
WIN_ShowWindow((WIN_WindowStruct *)photo);
//int ret_= WIN_RunBlock ((WIN_WindowStruct *)photo);
int ret_=0;
//myfree (bitmap.buff);
photo->memData=bitmap.buff;
return ret_;
}
2025-07-05 19:47:28 +08:00
//<2F><>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD>ͼ<EFBFBD><CDBC>
2025-06-27 00:32:57 +08:00
int PHOTO_ShowPic (WIN_WindowStruct *base,WIN_PicStruct *pic)
{
WIN_PhotoStruct *photo=0;
int x,y,xsize,ysize;
if (base)
{
//WIN_GetWinPosOnLcd (base,&x,&y,&xsize,&ysize);
x=0;y=0;xsize=base->x_size;ysize=base->y_size;
}
else
{
x=0;y=0;xsize=WIN_GetWinStruct()->lcd->getLcdSizeX();ysize=WIN_GetWinStruct()->lcd->getLcdSizeY();
}
if (pic->xsize<xsize) {x+=(xsize-pic->xsize)/2;xsize=pic->xsize;}
if (pic->ysize<ysize) {y+=(ysize-pic->ysize)/2;ysize=pic->ysize;}
//photo=WIN_CreatPhoto (0,0,x,y,xsize,ysize);
photo=WIN_CreatPhoto (base,0,x,y,xsize,ysize);
PHOTO_SetPic (photo,pic);
photo->memData=mymalloc (photo->pic.xsize*photo->pic.ysize*2);
if (photo->memData)
{
mymemcpy (photo->memData,photo->pic.data,photo->pic.xsize*photo->pic.ysize*2);
photo->pic.data=photo->memData;
photo->win.pic.data=photo->memData;
}
WIN_ShowWindow((WIN_WindowStruct *)photo);
//int ret_= WIN_RunBlock ((WIN_WindowStruct *)photo);
int ret_=0;
return ret_;
}