2 * fbvis - a framebuffer image viewer
4 * Copyright (C) 2013 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) (((r) << 16) | ((g) << 8) | (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 int cols
, rows
, ch
;
29 static int head
, left
;
31 static struct termios termios
;
32 static int fullscreen
;
34 static void draw(void)
37 int bpp
= FBM_BPP(fb_mode());
39 int re
= rs
+ MIN(rows
- rs
, fb_rows());
41 int ce
= cs
+ MIN(cols
- cs
, fb_cols());
42 int fbr
= (fb_rows() - (re
- rs
)) >> 1;
43 int fbc
= (fb_cols() - (ce
- cs
)) >> 1;
45 for (i
= rs
; i
< re
; i
++) {
46 for (j
= cs
; j
< ce
; j
++) {
47 unsigned char *src
= (void *) (buf
+ (i
* cols
+ j
) * ch
);
48 unsigned int *dst
= (void *) (row
+ (j
- cs
) * bpp
);
49 *dst
= FB_VAL(src
[0], src
[1], src
[2]);
51 fb_set(fbr
+ i
- rs
, fbc
, row
, ce
- cs
);
55 static void drawfs(void)
58 int fsrows
= rows
* fb_cols() / cols
;
59 int rs
= head
* MAX(0, fsrows
- fb_rows()) / MAX(1, rows
- fb_rows());
60 int bpp
= FBM_BPP(fb_mode());
62 for (i
= 0; i
< fb_rows(); i
++) {
63 int r
= (rs
+ i
) * rows
/ fsrows
;
65 memset(row
, 0, fb_cols() * bpp
);
66 for (j
= 0; j
< fb_cols() && r
< rows
; j
++) {
67 int c
= j
* cols
/ fb_cols();
68 unsigned char *src
= (void *) (buf
+ (r
* cols
+ c
) * ch
);
69 unsigned int *dst
= (void *) (row
+ j
* bpp
);
70 *dst
= FB_VAL(src
[0], src
[1], src
[2]);
72 fb_set(i
, 0, row
, fb_cols());
76 static int readkey(void)
79 if (read(0, &b
, 1) <= 0)
84 static int getcount(int def
)
86 int result
= count
? count
: def
;
91 static void term_setup(void)
93 struct termios newtermios
;
94 tcgetattr(0, &termios
);
96 newtermios
.c_lflag
&= ~ICANON
;
97 newtermios
.c_lflag
&= ~ECHO
;
98 tcsetattr(0, TCSAFLUSH
, &newtermios
);
101 static void term_cleanup(void)
103 tcsetattr(0, 0, &termios
);
106 static void mainloop(void)
108 int step
= fb_rows() / PAGESTEPS
;
109 int hstep
= fb_cols() / PAGESTEPS
;
113 while ((c
= readkey()) != -1) {
126 count
= count
* 10 + c
- '0';
130 head
+= step
* getcount(1);
133 head
-= step
* getcount(1);
136 left
+= hstep
* getcount(1);
139 left
-= hstep
* getcount(1);
145 head
= MAX(0, rows
- fb_rows());
148 head
= MAX(0, (rows
- fb_rows()) >> 1);
152 head
+= fb_rows() * getcount(1) - step
;
156 head
-= fb_rows() * getcount(1) - step
;
159 if (cols
> fb_cols())
160 fullscreen
= 1 - fullscreen
;
166 /* no need to redraw */
169 head
= REGION(0, MAX(0, rows
- fb_rows()), head
);
170 left
= REGION(0, MAX(0, cols
- fb_cols()), left
);
178 unsigned char *stbi_load(char const *filename
, int *x
, int *y
, int *comp
, int req_comp
);
180 static char *loadstbi(char *path
, int *h
, int *w
, int *ch
)
182 return (void *) stbi_load(path
, w
, h
, ch
, 3);
185 static char *loadlode(char *path
, int *h
, int *w
, int *ch
)
189 lodepng_decode32_file((void *) &s
, (void *) w
, (void *) h
, path
);
193 int main(int argc
, char *argv
[])
196 printf("usage: %s file\n", argv
[0]);
199 buf
= loadlode(argv
[1], &rows
, &cols
, &ch
);
201 buf
= loadstbi(argv
[1], &rows
, &cols
, &ch
);
203 printf("failed to load image <%s>\n", argv
[1]);