A little comment about a compilation matter: -lungif parameter is not usually correct...
[fbv.git] / main.c.old
blob5824f52cc038a83dea991067f76be0fe547117d3
1 /*
2         fbv  --  simple image viewer for the linux framebuffer
3         Copyright (C) 2000, 2001, 2003  Mateusz 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.
20 #include "config.h"
21 #include "fbv.h"
22 #include <stdio.h>
23 #include <termios.h>
24 #include <sys/time.h>
25 #include <sys/types.h>
26 #include <unistd.h>
27 #include <getopt.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #define min(a,b) ((a) < (b) ? (a) : (b))
31 #define max(a,b) ((a) > (b) ? (a) : (b))
32 #define SHOWDELAY 100000
33 #define NEXT_IMG -3
34 #define PREV_IMG -4
36 extern unsigned char * simple_resize(unsigned char * orgin,int ox,int oy,int dx,int dy);
37 extern unsigned char * alpha_resize(unsigned char * orgin,int ox,int oy,int dx,int dy);
38 extern unsigned char * color_average_resize(unsigned char * orgin,int ox,int oy,int dx,int dy);
41 int clear=1,delay=0,hide=1,dispinfo=1,allowstrech=0,opt_alpha = 0, allow_enlarging = 0, ignore_ratio = 0;
43 struct formathandler *fh_root=NULL;
45 struct termios oldtermios;
46 struct termios ourtermios;
48 int imm_getchar(int s,int us)
50         struct timeval tv;
51         unsigned char c;
52         fd_set fds;
53         FD_ZERO(&fds);
54         FD_SET(0,&fds);
55         tv.tv_sec=s; tv.tv_usec=us;
56         if(select(1,&fds,NULL,NULL,&tv))
57         {
58                 read(0,&c,1);
59                 return((int) c);
60         }
61         else
62         return(EOF);
65 void contoraw(void)
67         tcgetattr(0,&oldtermios);
68         memcpy(&ourtermios,&oldtermios,sizeof(struct termios));
69         ourtermios.c_lflag&=!(ECHO|ICANON);
70         tcsetattr(0,TCSANOW,&ourtermios);
72 void connorm(void)
74         tcsetattr(0,TCSANOW,&oldtermios);
78 void add_format(int (*picsize)(char *,int *,int*),int (*picread)(char *,unsigned char *,unsigned char**,int,int), int (*id)(char*))
80         struct formathandler *fhn;
81         fhn=(struct formathandler*) malloc(sizeof(struct formathandler));
82         fhn->get_size=picsize; fhn->get_pic=picread; fhn->id_pic=id;
83         fhn->next=fh_root; fh_root=fhn;
85 #ifdef FBV_SUPPORT_GIF
86         extern int fh_gif_getsize(char *,int *,int*);
87         extern int fh_gif_load(char *,unsigned char *,unsigned char **, int,int);
88         extern int fh_gif_id(char *);
89 #endif
90 #ifdef FBV_SUPPORT_JPEG
91         extern int fh_jpeg_getsize(char *,int *,int*);
92         extern int fh_jpeg_load(char *,unsigned char *,unsigned char **, int,int);
93         extern int fh_jpeg_id(char *);
94 #endif
95 #ifdef FBV_SUPPORT_PNG
96         extern int fh_png_getsize(char *,int *,int*);
97         extern int fh_png_load(char *,unsigned char *,unsigned char **,int,int);
98         extern int fh_png_id(char *);
99 #endif
100 #ifdef FBV_SUPPORT_BMP
101         extern int fh_bmp_getsize(char *,int *,int*);
102         extern int fh_bmp_load(char *,unsigned char *,unsigned char **, int,int);
103         extern int fh_bmp_id(char *);
104 #endif
106 void init_handlers(void)
108 #ifdef FBV_SUPPORT_GIF
109         add_format(fh_gif_getsize,fh_gif_load,fh_gif_id);
110 #endif
111 #ifdef FBV_SUPPORT_JPEG
112         add_format(fh_jpeg_getsize,fh_jpeg_load,fh_jpeg_id);
113 #endif
114 #ifdef FBV_SUPPORT_PNG
115         add_format(fh_png_getsize,fh_png_load,fh_png_id);
116 #endif
117 #ifdef FBV_SUPPORT_BMP
118         add_format(fh_bmp_getsize,fh_bmp_load,fh_bmp_id);
119 #endif
122 struct formathandler * fh_getsize(char *name,int *x,int *y)
124         struct formathandler *fh;
125         for(fh=fh_root;fh!=NULL;fh=fh->next)
126         {
127                 if(fh->id_pic(name))
128                         if(fh->get_size(name,x,y)==FH_ERROR_OK) return(fh);
129         }
130         return(NULL);
133 int show_image(char *name)
135         int x,y,xs,ys,xpos,ypos,xdelta,ydelta,c,eol,xstep,ystep,rfrsh,imx,imy;
136         unsigned char *buffer;
137         unsigned char *alpha = NULL;
138         struct formathandler *fh;
139         eol=1;
140         if((fh=fh_getsize(name,&x,&y)))
141         {
142                 buffer=(unsigned char *) malloc(x*y*3);
143                 if(fh->get_pic(name,buffer,&alpha,x,y)==FH_ERROR_OK)
144                 {
145                         if(clear) { printf("\033[H\033[J"); fflush(stdout); usleep(SHOWDELAY); } /* temporary solution */
146                         if(dispinfo) printf("%s\n%s\n%d x %d\n",IDSTRING,name,x,y); 
147                         contoraw();
148                         getCurrentRes(&xs,&ys);
149                         if((x>xs || y>ys) && allowstrech)
150                         {
151                                 if(ignore_ratio)
152                                 {
153                                         if(x > xs)
154                                                 imx = xs;
155                         
156                                         if(y > ys)
157                                                 imy = ys;
158                                 }
159                                 else
160                                 {
161                                         if( (y*xs/x) <= ys)
162                                         {
163                                                 imx=xs;
164                                                 imy=y*xs/x;
165                                         }
166                                         else
167                                         {
168                                                 imx=x*ys/y;
169                                                 imy=ys;
170                                         }
171                                 }
172                         
173                                 if(allowstrech==1)
174                                         buffer=simple_resize(buffer,x,y,imx,imy);
175                                 else
176                                         buffer=color_average_resize(buffer,x,y,imx,imy);
178                                 if(alpha)
179                                         alpha=alpha_resize(alpha,x,y,imx,imy);
181                                 x=imx; y=imy;
182                         }
183                         
184                         if(((x < xs) || (y < ys)) && allow_enlarging)
185                         {
186                                 int new_x, new_y;
187                                 if(ignore_ratio)
188                                 {
189                                         if(x < xs)
190                                                 new_x = xs;
191                                         if(y < ys)
192                                                 new_y = ys;
193                                 }
194                                 else
195                                 {
196                                 
197                                 }
198                         }
199                 
200                         if(x<xs) xpos=(xs-x)/2; else xpos=0;
201                         if(y<ys) ypos=(ys-y)/2; else ypos=0;
202                         xdelta=0; ydelta=0;
204                         xstep=min(max(x/20,1),xs);
205                         ystep=min(max(y/20,1),ys);
207                         for(eol=-1,rfrsh=1;eol==-1;)
208                         {
209                                 if(rfrsh)
210                                         fb_display(buffer, opt_alpha ? alpha : NULL, x,y,xdelta,ydelta,xpos,ypos);
211                                 rfrsh=0;
212                                 if(!delay)
213                                 {
214                                         c=getchar();
215                                         switch(c)
216                                         {
217                                                 case 'a': case 'D':
218                                                         xdelta-=xstep;
219                                                         if(xdelta<0) xdelta=0;
220                                                         rfrsh=1;
221                                                         break;
222                                                 case 'd': case 'C':
223                                                         if(xpos) break;
224                                                         xdelta+=xstep;
225                                                         if(xdelta>(x-xs)) xdelta=x-xs;
226                                                         rfrsh=1;
227                                                         break;
228                                                 case 'w': case 'A':
229                                                         ydelta-=ystep;
230                                                         if(ydelta<0) ydelta=0;
231                                                         rfrsh=1;
232                                                         break;
233                                                 case 'x': case 'B':
234                                                         if(ypos) break;
235                                                         ydelta+=ystep;
236                                                         if(ydelta>(y-ys)) ydelta=y-ys;
237                                                         rfrsh=1;
238                                                         break;
239                                                 case ' ': case 10: eol=1; break;
240                                                 case 'r': rfrsh=1; break;
241                                                 case '.': case '>': eol=NEXT_IMG; break;
242                                                 case ',': case '<': case 127: case 255: eol=PREV_IMG; break;
243                                                 case 'q': eol=0; break;
244                                         }
245                                 }
246                                 else
247                                 {
248                                         if(imm_getchar(delay / 10,delay % 10)=='q') eol=0; else eol=1;
249                                         break;
250                                 }
251                         }
252                         connorm();
253                         if(clear) { printf("\033[0m\033[H\033[J"); fflush(stdout); }
254                 }
255                 else
256                         printf("Unable to read file !\n");
257                 free(buffer);
258                 free(alpha);
259         }
260         else
261                 printf("Unable to read file or file format not recognized!\n");
262         
263         return(eol);
266 void help(char *name)
268         printf("Usage: %s [options] image1 image2 image3 ...\n\n"
269                    "Available options:\n"
270                    " --help     | -h : Show this help\n"
271                    " --alpha    | -a : Use alpha channel (if applicable)\n"
272                    " --noclear  | -c : Do not clear the screen before/after displaying image\n"
273                    " --unhide   | -u : Do not hide/show the cursor before/after displaying image\n"
274                    " --noinfo   | -i : Supress image information\n"
275                    " --stretch  | -f : Strech (using a simple resizing routine) the image to fit onto screen if necessary\n"
276                    " --colorstretch | -k : Strech (using a 'color average' resizing routine) the image to fit onto screen if necessary\n"
277                    " --enlarge    | -e : Enlarge the image to fit the whole screen if necessary\n"
278                    " --ignore-ratio | -r : Ignore the image aspect while resizing\n"
279                            " --delay    | -s <delay> slideshow, wait 'delay' tenths of a second before displaying each image\n\n"
280                    "Use a,d,w and x to scroll the image\n\n"
281                    "fbv 0.99 Copyright (C) 2000 - 2003 Mateusz Golicz, Tomasz Sterna.\n", name);
284 extern int optind;
285 extern char *optarg;
287 int main(int argc,char **argv)
289         int opt,a,r;
290         
291         static struct option long_options[] =
292         {
293         {"help",        no_argument,    0, 'h'},
294         {"noclear",     no_argument,    0, 'c'},
295         {"alpha",       no_argument,    0, 'a'},
296         {"unhide",      no_argument,    0, 'h'},
297         {"noinfo",      no_argument,    0, 'i'},
298         {"stretch",     no_argument,    0, 'f'},
299         {"colorstrech", no_argument,    0, 'k'},
300         {"delay",       required_argument, 0, 's'},
301         {"enlarge",     no_argument,    0, 'e'},
302         {"ignore-ratio", no_argument,   0, 'r'},
303         {0, 0, 0, 0}
304         };
306         init_handlers();                                                                                                                                           
307         
308         if(argc<2)
309                 help(argv[0]);
310         else
311         {
312                 for(;;)
313                 {
314                         opt=getopt_long_only(argc,argv,"achukfis:er",long_options,NULL);
315                         if(opt==EOF) break;
316                         switch(opt)
317                         {
318                                 case 'a': opt_alpha = 1; break;
319                                 case 'c': clear=0; break;
320                                 case 's': if(optarg) delay=atoi(optarg); break;
321                                 case 'u': hide=0; break;
322                                 case 'h': help(argv[0]); break;
323                                 case 'i': dispinfo=0; break;
324                                 case 'f': allowstrech=1; break;
325                                 case 'k': allowstrech=2; break;
326                                 case 'e': allow_enlarging = 1; break;
327                                 case 'r': ignore_ratio = 1; break;
328                         }
329                 }
330                 if(argv[optind]==NULL) {printf("You have to specify a filename!\n"); return(1);}
331                 while(imm_getchar(0,0)!=EOF);
332                 if(hide) printf("\033[?25l");
333                 for(a=optind;argv[a]!=NULL;a++) 
334                 {
335                         r=show_image(argv[a]);
336                         if(!r) break;
337                         if(r==PREV_IMG)
338                         {
339                                 if((a-1)>=optind)
340                                         a-=2;
341                                 else
342                                         a-=1;
343                         }
344                 }
345                 if(hide) printf("\033[?25h");
346         }
347         return(0);