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

478 lines
14 KiB
C
Raw Normal View History

2025-06-27 00:32:57 +08:00
#include "mywin_user_photo.h"
#include "bmp.h"
2025-06-27 00:32:57 +08:00
#include "ff.h"
#include "mywin_inc.h"
2025-06-27 00:32:57 +08:00
#include "picdeco.h"
#include "png.h"
#include "system_file.h"
#include <zlib.h>
2025-06-27 00:32:57 +08:00
#define WIN_PHOTO_TYPE "WIN_PhotoStruct"
static const char *g_popup_itmes[] = {
"<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) {
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣѭ<CFA2><D1AD>
if (msgLoop == 0) {
msgLoop = (void (*)(struct _WIN_WindowStruct *win,
WIN_MsgStruct *msg))PHOTO_defaultMsgLoop;
}
WIN_PhotoStruct *ret = mymalloc(sizeof(WIN_PhotoStruct));
// <20><><EFBFBD>ø<EFBFBD><C3B8><EFBFBD><EFBFBD>Ĺ<EFBFBD><C4B9><EFBFBD><ECBAAF>
if (ret) {
mymemset(ret, 0, sizeof(WIN_PhotoStruct));
if (0 == WIN_CreatWindowExt((WIN_WindowStruct *)ret, base, msgLoop, x, y,
x_size, y_size)) {
// <20><><EFBFBD><EFBFBD>ʧ<EFBFBD><CAA7>
myfree(ret);
ret = 0;
} else {
// <20><><EFBFBD><EFBFBD>
((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;
2025-06-27 00:32:57 +08:00
}
void WIN_DeletePhoto(WIN_PhotoStruct *photo) {
if (photo->memData) {
myfree(photo->memData);
}
if (photo->memDataGray) {
myfree(photo->memDataGray);
}
if (photo->memDataBit) {
myfree(photo->memDataBit);
}
// <20><><EFBFBD>ø<EFBFBD><C3B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ٺ<EFBFBD><D9BA><EFBFBD>
WIN_DeleteWindow((WIN_WindowStruct *)photo);
2025-06-27 00:32:57 +08:00
}
// <20><><EFBFBD><EFBFBD>ͼƬ
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));
2025-06-27 00:32:57 +08:00
}
static int go_trsGray(void *ptr) {
WIN_PhotoStruct *photo = ptr;
uint16_t *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-06-27 00:32:57 +08:00
}
// ת<><D7AA>Ϊ<EFBFBD>Ҷ<EFBFBD>ͼ
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)) {
WORKING_DoWork((WIN_WindowStruct *)photo, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɻҶ<EFBFBD>ͼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>",
go_trsGray, photo);
}
if (photo->grayTrs) {
if (photo->pic.data != photo->memDataGray)
photo->pic.data = photo->memDataGray;
else
photo->pic.data = photo->memData;
}
2025-06-27 00:32:57 +08:00
}
static uint16_t 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;
2025-06-27 00:32:57 +08:00
}
static uint16_t 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;
}
2025-06-27 00:32:57 +08:00
}
static uint16_t getBitRand(WIN_PicStruct *pic, int lev, int x, int y) {
if ((getBit(pic, x, y) & 0x1f) > lev)
return 0x1f;
else
return 0;
2025-06-27 00:32:57 +08:00
}
static int do_work(void *ptr) {
WIN_PhotoStruct *photo = ptr;
if (photo->memDataBit) {
uint16_t *ptr = photo->memDataBit;
uint16_t *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++) {
uint16_t 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-06-27 00:32:57 +08:00
}
// ת<><D7AA>Ϊλͼ
int PHOTO_TransforBit(WIN_PhotoStruct *photo) {
if (photo->grayTrs) {
if (photo->memDataBit == 0) {
photo->memDataBit = mymalloc(photo->pic.xsize * photo->pic.ysize * 2);
WORKING_DoWork((WIN_WindowStruct *)photo, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λͼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>", do_work,
photo);
}
}
if (photo->bitTrs) {
if (photo->pic.data != photo->memDataBit)
photo->pic.data = photo->memDataBit;
else
photo->pic.data = photo->memData;
}
return 0;
2025-06-27 00:32:57 +08:00
}
// <20><>Ϣ<EFBFBD><CFA2><EFBFBD>Ļ<EFBFBD><C4BB>ƺ<EFBFBD><C6BA><EFBFBD>
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);
2025-06-27 00:32:57 +08:00
}
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) {
// <20><><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD>
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) {
// ת<><D7AA>Ϊ<EFBFBD>Ҷ<EFBFBD>ͼ
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) {
// ת<><D7AA>Ϊλͼ
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) {
// <20>˳<EFBFBD>
((WIN_WindowStruct *)photo)->deleteWindow((WIN_WindowStruct *)photo);
}
2025-06-27 00:32:57 +08:00
}
// <20><>Ϣ<EFBFBD><CFA2><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><CFA2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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:
// <20>ȴ<EFBFBD><C8B4>ϴε<CFB4><CEB5><EFBFBD>ʾˢ<CABE><CBA2>
// 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;
}
2025-06-27 00:32:57 +08:00
}
typedef struct {
uint8_t *name;
BITMAP_Struct *bitmap;
} decode_jpg_struct;
2025-06-27 00:32:57 +08:00
// ͼƬ<CDBC><C6AC><EFBFBD><EFBFBD><EBB9A4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
static int decode_jpg(void *ptr) {
decode_jpg_struct *p = ptr;
return JPEG_Decode(p->name, p->bitmap);
2025-06-27 00:32:57 +08:00
}
typedef struct {
uint8_t *name;
BMP_DecodeStruct *bmp;
} decode_bmp_struct;
2025-06-27 00:32:57 +08:00
static int decode_bmp(void *ptr) {
decode_bmp_struct *p = ptr;
return BMP_Decode(p->name, p->bmp);
2025-06-27 00:32:57 +08:00
}
typedef struct {
char *name;
WIN_PicStruct *pic;
} decode_png_struct;
// <20><><EFBFBD><EFBFBD>pngͼƬ<CDBC><C6AC><EFBFBD>ɹ<EFBFBD><C9B9><EFBFBD><EFBFBD><EFBFBD>1<EFBFBD><31>ʧ<EFBFBD>ܷ<EFBFBD><DCB7><EFBFBD>0
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-06-27 00:32:57 +08:00
}
// <20><>ʾ<EFBFBD><CABE>Ƭ
int PHOTO_ShowPhoto(WIN_WindowStruct *base, char *name) {
// <20><><EFBFBD><EFBFBD>ͼƬ
BITMAP_Struct bitmap = {0};
WIN_PicStruct pic = {0};
uint8_t ret = 0;
// <20>ж<EFBFBD>ͼƬ<CDBC><C6AC>ʽ
int str_len = strlen(name);
char *p_str = &name[str_len - 4];
// <20><><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>ʾ<EFBFBD><CABE>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if (strcmp(p_str, ".jpg") == 0) {
decode_jpg_struct dec = {0};
dec.bitmap = &bitmap;
dec.name = (uint8_t *)name;
ret = WORKING_DoWork(base, "JPG<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>С<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>", decode_jpg, &dec);
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 = (uint8_t *)name;
dec.bmp = (BMP_DecodeStruct *)&bitmap; // <20><><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);
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;
ret = WORKING_DoWork(base, "PNG<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>С<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>", decode_png, &dec);
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-06-27 00:32:57 +08:00
}
// <20><>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD>ͼ<EFBFBD><CDBC>
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_;
2025-06-27 00:32:57 +08:00
}