2 fbv -- simple image viewer for the linux framebuffer
3 Copyright (C) 2000, 2001, 2003, 2004 Mateusz 'mteg' Golicz
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 #include <sys/types.h>
32 #define PAN_STEPPING 20
34 static int opt_clear
= 1,
41 opt_ignore_aspect
= 0;
45 void setup_console(int t
)
47 struct termios our_termios
;
48 static struct termios old_termios
;
52 tcgetattr(0, &old_termios
);
53 memcpy(&our_termios
, &old_termios
, sizeof(struct termios
));
54 our_termios
.c_lflag
&= !(ECHO
| ICANON
);
55 tcsetattr(0, TCSANOW
, &our_termios
);
58 tcsetattr(0, TCSANOW
, &old_termios
);
62 static inline void do_rotate(struct image
*i
, int rot
)
66 unsigned char *image
, *alpha
= NULL
;
69 image
= rotate(i
->rgb
, i
->width
, i
->height
, rot
);
71 alpha
= alpha_rotate(i
->alpha
, i
->width
, i
->height
, rot
);
92 static inline void do_enlarge(struct image
*i
, int screen_width
, int screen_height
, int ignoreaspect
)
94 if(((i
->width
> screen_width
) || (i
->height
> screen_height
)) && (!ignoreaspect
))
96 if((i
->width
< screen_width
) || (i
->height
< screen_height
))
98 int xsize
= i
->width
, ysize
= i
->height
;
99 unsigned char * image
, * alpha
= NULL
;
103 if(i
->width
< screen_width
)
104 xsize
= screen_width
;
105 if(i
->height
< screen_height
)
106 ysize
= screen_height
;
111 if((i
->height
* screen_width
/ i
->width
) <= screen_height
)
113 xsize
= screen_width
;
114 ysize
= i
->height
* screen_width
/ i
->width
;
118 if((i
->width
* screen_height
/ i
->height
) <= screen_width
)
120 xsize
= i
->width
* screen_height
/ i
->height
;
121 ysize
= screen_height
;
126 image
= simple_resize(i
->rgb
, i
->width
, i
->height
, xsize
, ysize
);
128 alpha
= alpha_resize(i
->alpha
, i
->width
, i
->height
, xsize
, ysize
);
145 static inline void do_fit_to_screen(struct image
*i
, int screen_width
, int screen_height
, int ignoreaspect
, int cal
)
147 if((i
->width
> screen_width
) || (i
->height
> screen_height
))
149 unsigned char * new_image
, * new_alpha
= NULL
;
150 int nx_size
= i
->width
, ny_size
= i
->height
;
154 if(i
->width
> screen_width
)
155 nx_size
= screen_width
;
156 if(i
->height
> screen_height
)
157 ny_size
= screen_height
;
161 if((i
->height
* screen_width
/ i
->width
) <= screen_height
)
163 nx_size
= screen_width
;
164 ny_size
= i
->height
* screen_width
/ i
->width
;
168 nx_size
= i
->width
* screen_height
/ i
->height
;
169 ny_size
= screen_height
;
174 new_image
= color_average_resize(i
->rgb
, i
->width
, i
->height
, nx_size
, ny_size
);
176 new_image
= simple_resize(i
->rgb
, i
->width
, i
->height
, nx_size
, ny_size
);
179 new_alpha
= alpha_resize(i
->alpha
, i
->width
, i
->height
, nx_size
, ny_size
);
188 i
->alpha
= new_alpha
;
196 int show_image(char *filename
)
198 int (*load
)(char *, unsigned char *, unsigned char **, int, int);
200 unsigned char * image
= NULL
;
201 unsigned char * alpha
= NULL
;
203 int x_size
, y_size
, screen_width
, screen_height
;
204 int x_pan
= 0, y_pan
= 0, x_offs
= 0, y_offs
= 0, refresh
= 1, c
, ret
= 1;
205 int delay
= opt_delay
, retransform
= 1;
207 int transform_stretch
= opt_stretch
, transform_enlarge
= opt_enlarge
, transform_cal
= (opt_stretch
== 2),
208 transform_iaspect
= opt_ignore_aspect
, transform_rotation
= 0;
211 memset(&i
, 0, sizeof(struct image
));
213 #ifdef FBV_SUPPORT_GIF
214 if(fh_gif_id(filename
))
215 if(fh_gif_getsize(filename
, &x_size
, &y_size
) == FH_ERROR_OK
)
222 #ifdef FBV_SUPPORT_PNG
223 if(fh_png_id(filename
))
224 if(fh_png_getsize(filename
, &x_size
, &y_size
) == FH_ERROR_OK
)
231 #ifdef FBV_SUPPORT_JPEG
232 if(fh_jpeg_id(filename
))
233 if(fh_jpeg_getsize(filename
, &x_size
, &y_size
) == FH_ERROR_OK
)
240 #ifdef FBV_SUPPORT_BMP
241 if(fh_bmp_id(filename
))
242 if(fh_bmp_getsize(filename
, &x_size
, &y_size
) == FH_ERROR_OK
)
248 fprintf(stderr
, "%s: Unable to access file or file format unknown.\n", filename
);
253 if(!(image
= (unsigned char*) malloc(x_size
* y_size
* 3)))
255 fprintf(stderr
, "%s: Out of memory.\n", filename
);
259 if(load(filename
, image
, &alpha
, x_size
, y_size
) != FH_ERROR_OK
)
261 fprintf(stderr
, "%s: Image data is corrupt?\n", filename
);
273 getCurrentRes(&screen_width
, &screen_height
);
291 if(transform_rotation
)
292 do_rotate(&i
, transform_rotation
);
294 if(transform_stretch
)
295 do_fit_to_screen(&i
, screen_width
, screen_height
, transform_iaspect
, transform_cal
);
297 if(transform_enlarge
)
298 do_enlarge(&i
, screen_width
, screen_height
, transform_iaspect
);
301 refresh
= 1; retransform
= 0;
304 printf("\033[H\033[J");
308 printf("fbv - The Framebuffer Viewer\n%s\n%d x %d\n", filename
, x_size
, y_size
);
312 if(i
.width
< screen_width
)
313 x_offs
= (screen_width
- i
.width
) / 2;
317 if(i
.height
< screen_height
)
318 y_offs
= (screen_height
- i
.height
) / 2;
322 fb_display(i
.rgb
, i
.alpha
, i
.width
, i
.height
, x_pan
, y_pan
, x_offs
, y_offs
);
329 tv
.tv_sec
= delay
/ 10;
330 tv
.tv_usec
= (delay
% 10) * 100000;
334 if(select(1, &fds
, NULL
, NULL
, &tv
) <= 0)
346 case ' ': case 10: case 13:
357 if(x_pan
== 0) break;
358 x_pan
-= i
.width
/ PAN_STEPPING
;
359 if(x_pan
< 0) x_pan
= 0;
364 if(x_pan
>= (i
.width
- screen_width
)) break;
365 x_pan
+= i
.width
/ PAN_STEPPING
;
366 if(x_pan
> (i
.width
- screen_width
)) x_pan
= i
.width
- screen_width
;
370 if(y_pan
== 0) break;
371 y_pan
-= i
.height
/ PAN_STEPPING
;
372 if(y_pan
< 0) y_pan
= 0;
377 if(y_pan
>= (i
.height
- screen_height
)) break;
378 y_pan
+= i
.height
/ PAN_STEPPING
;
379 if(y_pan
> (i
.height
- screen_height
)) y_pan
= i
.height
- screen_height
;
383 transform_stretch
= !transform_stretch
;
387 transform_enlarge
= !transform_enlarge
;
391 transform_cal
= !transform_cal
;
395 transform_iaspect
= !transform_iaspect
;
400 transform_iaspect
= 0;
401 transform_enlarge
= 0;
402 transform_stretch
= 0;
406 transform_rotation
-= 1;
407 if(transform_rotation
< 0)
408 transform_rotation
+= 4;
412 transform_rotation
+= 1;
413 if(transform_rotation
> 3)
414 transform_rotation
-= 4;
425 printf("\033[H\033[J");
441 void help(char *name
)
443 printf("Usage: %s [options] image1 image2 image3 ...\n\n"
444 "Available options:\n"
445 " --help | -h : Show this help\n"
446 " --alpha | -a : Use the alpha channel (if applicable)\n"
447 " --dontclear | -c : Do not clear the screen before and after displaying the image\n"
448 " --donthide | -u : Do not hide the cursor before and after displaying the image\n"
449 " --noinfo | -i : Supress image information\n"
450 " --stretch | -f : Strech (using a simple resizing routine) the image to fit onto screen if necessary\n"
451 " --colorstretch| -k : Strech (using a 'color average' resizing routine) the image to fit onto screen if necessary\n"
452 " --enlarge | -e : Enlarge the image to fit the whole screen if necessary\n"
453 " --ignore-aspect| -r : Ignore the image aspect while resizing\n"
454 " --delay <d> | -s <delay> : Slideshow, 'delay' is the slideshow delay in tenths of seconds.\n\n"
456 " r : Redraw the image\n"
457 " a, d, w, x : Pan the image\n"
458 " f : Toggle resizing on/off\n"
459 " k : Toggle resizing quality\n"
460 " e : Toggle enlarging on/off\n"
461 " i : Toggle respecting the image aspect on/off\n"
462 " n : Rotate the image 90 degrees left\n"
463 " m : Rotate the image 90 degrees right\n"
464 " p : Disable all transformations\n"
465 "Copyright (C) 2000 - 2004 Mateusz Golicz, Tomasz Sterna.\n", name
);
468 void sighandler(int s
)
480 int main(int argc
, char **argv
)
482 static struct option long_options
[] =
484 {"help", no_argument
, 0, 'h'},
485 {"noclear", no_argument
, 0, 'c'},
486 {"alpha", no_argument
, 0, 'a'},
487 {"unhide", no_argument
, 0, 'u'},
488 {"noinfo", no_argument
, 0, 'i'},
489 {"stretch", no_argument
, 0, 'f'},
490 {"colorstrech", no_argument
, 0, 'k'},
491 {"delay", required_argument
, 0, 's'},
492 {"enlarge", no_argument
, 0, 'e'},
493 {"ignore-aspect", no_argument
, 0, 'r'},
501 fprintf(stderr
, "Error: Required argument missing.\n");
505 while((c
= getopt_long_only(argc
, argv
, "hcauifks:er", long_options
, NULL
)) != EOF
)
516 opt_delay
= atoi(optarg
);
537 opt_ignore_aspect
= 1;
545 fprintf(stderr
, "Required argument missing! Consult %s -h.\n", argv
[0]);
549 signal(SIGHUP
, sighandler
);
550 signal(SIGINT
, sighandler
);
551 signal(SIGQUIT
, sighandler
);
552 signal(SIGSEGV
, sighandler
);
553 signal(SIGTERM
, sighandler
);
554 signal(SIGABRT
, sighandler
);
564 for(i
= optind
; argv
[i
]; )
566 int r
= show_image(argv
[i
]);