2 * fbvis - a framebuffer image viewer
4 * Copyright (C) 2013-2014 Ali Gholami Rudi
6 * This file is released under the Modified BSD license.
18 /* optimized version of fb_val() */
19 #define FB_VAL(r, g, b) fb_val(r, g, b)
22 #define CTRLKEY(x) ((x) - 96)
23 #define MIN(a, b) ((a) < (b) ? (a) : (b))
24 #define MAX(a, b) ((a) > (b) ? (a) : (b))
25 #define REGION(a, b, x) (MIN(b, MAX(x, a)))
27 static unsigned char *obuf
; /* original image */
28 static int ocols
, orows
; /* obuf dimensions */
29 static int ch
; /* bytes per pixel */
30 static unsigned char *buf
; /* zoomed image for framebuffer */
31 static int cols
, rows
; /* buf dimensions */
32 static int czoom
; /* current zoom */
33 static int head
, left
; /* current viewing position */
34 static int count
; /* command prefix */
35 static struct termios termios
;
37 static int curfile
= -1;
43 static void zoom(int z
)
45 int bpp
= FBM_BPP(fb_mode());
49 c
= 100 * fb_rows() / orows
;
51 c
= 100 * fb_cols() / ocols
;
53 cols
= ocols
* c
/ 100;
54 rows
= orows
* c
/ 100;
55 buf
= malloc(rows
* cols
* bpp
);
56 for (i
= 0; i
< rows
; i
++) {
57 for (j
= 0; j
< cols
; j
++) {
58 unsigned char *src
= obuf
+ (i
* 100 / c
* ocols
+
60 unsigned int *dst
= (void *) buf
+ (i
* cols
+ j
) * bpp
;
61 *dst
= FB_VAL(src
[0], src
[1], src
[2]);
66 static void draw(void)
68 int bpp
= FBM_BPP(fb_mode());
70 int re
= rs
+ MIN(rows
- rs
, fb_rows());
72 int ce
= cs
+ MIN(cols
- cs
, fb_cols());
73 int fbr
= (fb_rows() - (re
- rs
)) >> 1;
74 int fbc
= (fb_cols() - (ce
- cs
)) >> 1;
76 for (i
= rs
; i
< re
; i
++)
77 fb_set(fbr
+ i
- rs
, fbc
, buf
+ (i
* cols
+ cs
) * bpp
, ce
- cs
);
80 unsigned char *stbi_load(char const *filename
, int *x
, int *y
, int *comp
, int req_comp
);
81 char *ppm_load(char *path
, int *h
, int *w
);
83 static int loadfile(char *path
)
85 FILE *fp
= fopen(path
, "r");
91 lodepng_decode32_file(&obuf
, (void *) &ocols
, (void *) &orows
, path
);
93 obuf
= stbi_load(path
, &ocols
, &orows
, &ch
, 0);
96 obuf
= (void *) ppm_load(path
, &orows
, &ocols
);
101 static void printinfo(void)
103 printf("\rFBVIS: file:%s\x1b[K\r", files
[curfile
]);
107 static void freebufs(void)
115 static int nextfile(int dir
)
121 if (curfile
< 0 || !files
[curfile
])
123 if (!loadfile(files
[curfile
]))
126 printf("failed to load image <%s>\n", files
[curfile
]);
133 static int readkey(void)
136 if (read(0, &b
, 1) <= 0)
141 static int getcount(int def
)
143 int result
= count
? count
: def
;
148 static void term_setup(void)
150 struct termios newtermios
;
151 tcgetattr(0, &termios
);
152 newtermios
= termios
;
153 newtermios
.c_lflag
&= ~ICANON
;
154 newtermios
.c_lflag
&= ~ECHO
;
155 tcsetattr(0, TCSAFLUSH
, &newtermios
);
158 static void term_cleanup(void)
160 tcsetattr(0, 0, &termios
);
163 static void mainloop(void)
165 int step
= fb_rows() / PAGESTEPS
;
166 int hstep
= fb_cols() / PAGESTEPS
;
169 while ((c
= readkey()) != -1) {
172 head
+= step
* getcount(1);
175 head
-= step
* getcount(1);
178 left
+= hstep
* getcount(1);
181 left
-= hstep
* getcount(1);
187 head
= MAX(0, rows
- fb_rows());
190 head
= MAX(0, (rows
- fb_rows()) >> 1);
194 head
+= fb_rows() * getcount(1) - step
;
198 head
-= fb_rows() * getcount(1) - step
;
215 if (nextfile(getcount(1)))
221 if (nextfile(-getcount(1)))
232 count
= count
* 10 + c
- '0';
235 /* no need to redraw */
238 head
= REGION(0, MAX(0, rows
- fb_rows()), head
);
239 left
= REGION(0, MAX(0, cols
- fb_cols()), left
);
244 int main(int argc
, char *argv
[])
247 printf("usage: %s file\n", argv
[0]);