working
This commit is contained in:
parent
1bd37963c8
commit
dffe16eeff
4 changed files with 205 additions and 11 deletions
117
mimview/image.c
Normal file
117
mimview/image.c
Normal file
|
|
@ -0,0 +1,117 @@
|
||||||
|
#include "mimview.h"
|
||||||
|
|
||||||
|
#include <stb_image.h>
|
||||||
|
#include <stb_ds.h>
|
||||||
|
|
||||||
|
image_t* images = NULL;
|
||||||
|
static int oldw = 0, oldh = 0;
|
||||||
|
static unsigned char* buffer = NULL;
|
||||||
|
|
||||||
|
void image_init(void) {
|
||||||
|
unsigned char* d = ((MwLLCommonPixmap)pxdata)->raw;
|
||||||
|
int w = ((MwLLCommonPixmap)pxdata)->width;
|
||||||
|
int h = ((MwLLCommonPixmap)pxdata)->height;
|
||||||
|
if(oldw != w || oldh != h) {
|
||||||
|
int y, x;
|
||||||
|
if(buffer != NULL) free(buffer);
|
||||||
|
for(y = 0; y < h; y++) {
|
||||||
|
for(x = 0; x < w; x++) {
|
||||||
|
unsigned char* px = &d[(y * w + x) * 4];
|
||||||
|
if(((y / 16) + (x / 16)) % 2) {
|
||||||
|
px[0] = px[1] = px[2] = 128;
|
||||||
|
} else {
|
||||||
|
px[0] = px[1] = px[2] = 64;
|
||||||
|
}
|
||||||
|
px[3] = 255;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
buffer = malloc(w * h * 4);
|
||||||
|
memcpy(buffer, d, w * h * 4);
|
||||||
|
} else {
|
||||||
|
memcpy(d, buffer, w * h * 4);
|
||||||
|
}
|
||||||
|
oldw = w;
|
||||||
|
oldh = h;
|
||||||
|
|
||||||
|
MwLLPixmapUpdate(pxdata);
|
||||||
|
MwForceRender(image);
|
||||||
|
}
|
||||||
|
|
||||||
|
void image_add(const char* path) {
|
||||||
|
image_t img;
|
||||||
|
img.path = MDEStringDuplicate(path);
|
||||||
|
img.data = NULL;
|
||||||
|
img.width = 0;
|
||||||
|
img.height = 0;
|
||||||
|
img.x = 0;
|
||||||
|
img.y = 0;
|
||||||
|
img.scale = 0;
|
||||||
|
arrput(images, img);
|
||||||
|
}
|
||||||
|
|
||||||
|
void image_render(void) {
|
||||||
|
if(current < arrlen(images) && images[current].data == NULL) {
|
||||||
|
int w, h, ch;
|
||||||
|
unsigned char* d;
|
||||||
|
again:;
|
||||||
|
d = stbi_load(images[current].path, &w, &h, &ch, 4);
|
||||||
|
if(d != NULL) {
|
||||||
|
int pw = ((MwLLCommonPixmap)pxdata)->width;
|
||||||
|
int ph = ((MwLLCommonPixmap)pxdata)->height;
|
||||||
|
double sw = (double)w / pw;
|
||||||
|
double sh = (double)h / ph;
|
||||||
|
|
||||||
|
images[current].data = d;
|
||||||
|
images[current].width = w;
|
||||||
|
images[current].height = h;
|
||||||
|
images[current].scale = sw > sh ? sw : sh;
|
||||||
|
} else {
|
||||||
|
free(images[current].path);
|
||||||
|
arrdel(images, current);
|
||||||
|
if(arrlen(images) <= current) {
|
||||||
|
current = 0;
|
||||||
|
}
|
||||||
|
goto again;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(current < arrlen(images)) {
|
||||||
|
unsigned char* d = ((MwLLCommonPixmap)pxdata)->raw;
|
||||||
|
int y;
|
||||||
|
int x;
|
||||||
|
int w = ((MwLLCommonPixmap)pxdata)->width;
|
||||||
|
int h = ((MwLLCommonPixmap)pxdata)->height;
|
||||||
|
int ox = (w - images[current].width / images[current].scale) / 2 - images[current].x / images[current].scale;
|
||||||
|
int oy = (h - images[current].height / images[current].scale) / 2 - images[current].y / images[current].scale;
|
||||||
|
char str[128];
|
||||||
|
|
||||||
|
sprintf(str, "mimview [%d of %d] %s", current + 1, arrlen(images), images[current].path);
|
||||||
|
|
||||||
|
MwVaApply(window,
|
||||||
|
MwNtitle, str,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
for(y = (oy < 0 ? 0 : 0); y < h + (oy < 0 ? -oy : 0); y++) {
|
||||||
|
for(x = (ox < 0 ? 0 : 0); x < w + (ox < 0 ? -ox : 0); x++) {
|
||||||
|
if(0 <= (y + oy) && (y + oy) < h && 0 <= (x + ox) && (x + ox) < w) {
|
||||||
|
int ix = x * images[current].scale;
|
||||||
|
int iy = y * images[current].scale;
|
||||||
|
unsigned char* opx;
|
||||||
|
unsigned char* ipx;
|
||||||
|
if(0 <= iy && iy < images[current].height && 0 <= ix && ix < images[current].width) {
|
||||||
|
int i;
|
||||||
|
opx = &d[((y + oy) * w + x + ox) * 4];
|
||||||
|
ipx = &images[current].data[(iy * images[current].width + ix) * 4];
|
||||||
|
|
||||||
|
for(i = 0; i < 3; i++) {
|
||||||
|
opx[i] *= (255 - ipx[3]) / 255.0;
|
||||||
|
opx[i] += ipx[i] * (ipx[3] / 255.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MwLLPixmapUpdate(pxdata);
|
||||||
|
MwForceRender(image);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,12 +1,15 @@
|
||||||
#include "mimview.h"
|
#include "mimview.h"
|
||||||
|
|
||||||
|
#include <stb_ds.h>
|
||||||
|
|
||||||
#define ButtonWidth 32
|
#define ButtonWidth 32
|
||||||
#define ButtonHeight 24
|
#define ButtonHeight 24
|
||||||
|
|
||||||
MwWidget window, menu, image;
|
MwWidget window, menu, image;
|
||||||
|
MwWidget bprev, bnext, bzoomin, bzoomout;
|
||||||
MwLLPixmap pxprojector, pxdata = NULL;
|
MwLLPixmap pxprojector, pxdata = NULL;
|
||||||
static MwLLPixmap pxprev, pxnext, pxzoomin, pxzoomout;
|
static MwLLPixmap pxprev, pxnext, pxzoomin, pxzoomout;
|
||||||
static MwWidget bprev, bnext, sep, bzoomin, bzoomout;
|
static MwWidget sep;
|
||||||
|
|
||||||
static void resize(MwWidget handle, void* user, void* client) {
|
static void resize(MwWidget handle, void* user, void* client) {
|
||||||
int y = MwGetInteger(menu, MwNheight);
|
int y = MwGetInteger(menu, MwNheight);
|
||||||
|
|
@ -18,17 +21,18 @@ static void resize(MwWidget handle, void* user, void* client) {
|
||||||
|
|
||||||
if(pxdata != NULL) MwLLDestroyPixmap(pxdata);
|
if(pxdata != NULL) MwLLDestroyPixmap(pxdata);
|
||||||
iw = ww - 10;
|
iw = ww - 10;
|
||||||
ih = wh - 5 - ButtonHeight - 5;
|
ih = wh - 5 - 5 - ButtonHeight - 5;
|
||||||
data = malloc(iw * ih * 4);
|
data = malloc(iw * ih * 4);
|
||||||
memset(data, 0, iw * ih * 4);
|
memset(data, 0, iw * ih * 4);
|
||||||
pxdata = MwLoadRaw(window, data, iw, ih);
|
pxdata = MwLoadRaw(window, data, iw, ih);
|
||||||
free(data);
|
free(data);
|
||||||
|
image_init();
|
||||||
MwVaApply(image,
|
MwVaApply(image,
|
||||||
MwNpixmap, pxdata,
|
MwNpixmap, pxdata,
|
||||||
MwNx, 5,
|
MwNx, 5,
|
||||||
MwNy, y + 5,
|
MwNy, y + 5,
|
||||||
MwNwidth, ww - 10,
|
MwNwidth, ww - 10,
|
||||||
MwNheight, wh - 5 - ButtonHeight - 5,
|
MwNheight, wh - 5 - 5 - ButtonHeight - 5,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
bx = (ww - 10 - (ButtonWidth * 2 + 5) * 2) / 2;
|
bx = (ww - 10 - (ButtonWidth * 2 + 5) * 2) / 2;
|
||||||
|
|
@ -62,13 +66,18 @@ static void resize(MwWidget handle, void* user, void* client) {
|
||||||
MwNwidth, ButtonWidth,
|
MwNwidth, ButtonWidth,
|
||||||
MwNheight, ButtonHeight,
|
MwNheight, ButtonHeight,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
|
if(current < arrlen(images)) {
|
||||||
|
image_render();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char** argv) {
|
int main(int argc, char** argv) {
|
||||||
int pad;
|
int pad;
|
||||||
|
int i;
|
||||||
MwLibraryInit();
|
MwLibraryInit();
|
||||||
|
|
||||||
window = MwVaCreateWidget(MwWindowClass, "main", NULL, MwDEFAULT, MwDEFAULT, 320, 240,
|
window = MwVaCreateWidget(MwWindowClass, "main", NULL, MwDEFAULT, MwDEFAULT, 320, 320,
|
||||||
MwNtitle, "mimview",
|
MwNtitle, "mimview",
|
||||||
NULL);
|
NULL);
|
||||||
menu = MwCreateWidget(MwMenuClass, "menu", window, 0, 0, 0, 0);
|
menu = MwCreateWidget(MwMenuClass, "menu", window, 0, 0, 0, 0);
|
||||||
|
|
@ -100,20 +109,26 @@ int main(int argc, char** argv) {
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
MwVaApply(bzoomin,
|
MwVaApply(bzoomin,
|
||||||
MwNpixmap, pxzoomout,
|
MwNpixmap, pxzoomin,
|
||||||
MwNpadding, pad,
|
MwNpadding, pad,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
MwVaApply(bzoomout,
|
MwVaApply(bzoomout,
|
||||||
MwNpixmap, pxzoomin,
|
MwNpixmap, pxzoomout,
|
||||||
MwNpadding, pad,
|
MwNpadding, pad,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
MwAddUserHandler(window, MwNresizeHandler, resize, NULL);
|
MwAddUserHandler(window, MwNresizeHandler, resize, NULL);
|
||||||
|
|
||||||
ui_init();
|
|
||||||
|
|
||||||
resize(window, NULL, NULL);
|
resize(window, NULL, NULL);
|
||||||
|
|
||||||
|
for(i = 1; i < argc; i++) {
|
||||||
|
image_add(argv[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
image_render();
|
||||||
|
|
||||||
|
ui_init();
|
||||||
|
|
||||||
MwLoop(window);
|
MwLoop(window);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,11 +16,29 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
typedef struct image {
|
||||||
|
char* path;
|
||||||
|
unsigned char* data;
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
int x;
|
||||||
|
int y;
|
||||||
|
double scale;
|
||||||
|
} image_t;
|
||||||
|
|
||||||
/* main.c */
|
/* main.c */
|
||||||
extern MwWidget window, menu;
|
extern MwWidget window, menu, image;
|
||||||
extern MwLLPixmap pxprojector;
|
extern MwLLPixmap pxprojector, pxdata;
|
||||||
|
extern MwWidget bprev, bnext, bzoomin, bzoomout;
|
||||||
|
|
||||||
/* ui.c */
|
/* ui.c */
|
||||||
void ui_init(void);
|
extern int current;
|
||||||
|
void ui_init(void);
|
||||||
|
|
||||||
|
/* image.c */
|
||||||
|
extern image_t* images;
|
||||||
|
void image_init(void);
|
||||||
|
void image_add(const char* path);
|
||||||
|
void image_render(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
44
mimview/ui.c
44
mimview/ui.c
|
|
@ -1,6 +1,9 @@
|
||||||
#include "mimview.h"
|
#include "mimview.h"
|
||||||
|
|
||||||
|
#include <stb_ds.h>
|
||||||
|
|
||||||
static void* help_about;
|
static void* help_about;
|
||||||
|
int current = 0;
|
||||||
|
|
||||||
static void menu_menu(MwWidget handle, void* user, void* client) {
|
static void menu_menu(MwWidget handle, void* user, void* client) {
|
||||||
if(client == help_about) {
|
if(client == help_about) {
|
||||||
|
|
@ -8,6 +11,43 @@ static void menu_menu(MwWidget handle, void* user, void* client) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void bprev_activate(MwWidget handle, void* user, void* client) {
|
||||||
|
current--;
|
||||||
|
if(current == -1) current = arrlen(images) - 1;
|
||||||
|
if(current == -1) current = 0;
|
||||||
|
if(current < arrlen(images)) {
|
||||||
|
image_init();
|
||||||
|
image_render();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void bnext_activate(MwWidget handle, void* user, void* client) {
|
||||||
|
current++;
|
||||||
|
if(current == arrlen(images)) current = 0;
|
||||||
|
if(current < arrlen(images)) {
|
||||||
|
image_init();
|
||||||
|
image_render();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void bzoomin_activate(MwWidget handle, void* user, void* client) {
|
||||||
|
if(current < arrlen(images)) {
|
||||||
|
if(images[current].scale >= 0.2) {
|
||||||
|
images[current].scale /= 2;
|
||||||
|
}
|
||||||
|
image_init();
|
||||||
|
image_render();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void bzoomout_activate(MwWidget handle, void* user, void* client) {
|
||||||
|
if(current < arrlen(images)) {
|
||||||
|
images[current].scale *= 2;
|
||||||
|
image_init();
|
||||||
|
image_render();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ui_init(void) {
|
void ui_init(void) {
|
||||||
void* m;
|
void* m;
|
||||||
|
|
||||||
|
|
@ -15,4 +55,8 @@ void ui_init(void) {
|
||||||
help_about = MwMenuAdd(menu, m, "About");
|
help_about = MwMenuAdd(menu, m, "About");
|
||||||
|
|
||||||
MwAddUserHandler(menu, MwNmenuHandler, menu_menu, NULL);
|
MwAddUserHandler(menu, MwNmenuHandler, menu_menu, NULL);
|
||||||
|
MwAddUserHandler(bprev, MwNactivateHandler, bprev_activate, NULL);
|
||||||
|
MwAddUserHandler(bnext, MwNactivateHandler, bnext_activate, NULL);
|
||||||
|
MwAddUserHandler(bzoomin, MwNactivateHandler, bzoomin_activate, NULL);
|
||||||
|
MwAddUserHandler(bzoomout, MwNactivateHandler, bzoomout_activate, NULL);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue