Import of http://s-tech.elsat.net.pl/fbv/fbv-0.93b.tar.gz released the 2000-Nov-20...
[fbv.git] / main.c
blobd1ed9959490427da0ae8f92293128db7b49dd46c
1 #include "config.h"
2 #include "fbv.h"
3 #include <stdio.h>
4 #include <termios.h>
5 #include <sys/time.h>
6 #include <sys/types.h>
7 #include <unistd.h>
8 #define min(a,b) ((a) < (b) ? (a) : (b))
9 #define max(a,b) ((a) > (b) ? (a) : (b))
10 #define SHOWDELAY 100000
11 #define NEXT_IMG -3
12 #define PREV_IMG -4
13 #define IDSTRING "fbv 0.93b, s-tech"
15 extern unsigned char * simple_resize(unsigned char * orgin,int ox,int oy,int dx,int dy);
16 extern unsigned char * color_average_resize(unsigned char * orgin,int ox,int oy,int dx,int dy);
19 int clear=1,delay=0,hide=1,dispinfo=1,allowstrech=0;
21 struct formathandler *fh_root=NULL;
23 struct termios oldtermios;
24 struct termios ourtermios;
26 int imm_getchar(int s,int us)
28 struct timeval tv;
29 unsigned char c;
30 fd_set fds;
31 FD_ZERO(&fds);
32 FD_SET(0,&fds);
33 tv.tv_sec=s; tv.tv_usec=us;
34 if(select(1,&fds,NULL,NULL,&tv))
36 read(0,&c,1);
37 return((int) c);
39 else
40 return(EOF);
43 void contoraw(void)
45 tcgetattr(0,&oldtermios);
46 memcpy(&ourtermios,&oldtermios,sizeof(struct termios));
47 ourtermios.c_lflag&=!(ECHO|ICANON);
48 tcsetattr(0,TCSANOW,&ourtermios);
50 void connorm(void)
52 tcsetattr(0,TCSANOW,&oldtermios);
56 void add_format(int (*picsize)(char *,int *,int*),int (*picread)(char *,unsigned char *,int,int), int (*id)(char*))
58 struct formathandler *fhn;
59 fhn=(struct formathandler*) malloc(sizeof(struct formathandler));
60 fhn->get_size=picsize; fhn->get_pic=picread; fhn->id_pic=id;
61 fhn->next=fh_root; fh_root=fhn;
63 #ifdef FBV_SUPPORT_GIF
64 extern int fh_gif_getsize(char *,int *,int*);
65 extern int fh_gif_load(char *,unsigned char *,int,int);
66 extern int fh_gif_id(char *);
67 #endif
68 #ifdef FBV_SUPPORT_JPEG
69 extern int fh_jpeg_getsize(char *,int *,int*);
70 extern int fh_jpeg_load(char *,unsigned char *,int,int);
71 extern int fh_jpeg_id(char *);
72 #endif
73 #ifdef FBV_SUPPORT_PNG
74 extern int fh_png_getsize(char *,int *,int*);
75 extern int fh_png_load(char *,unsigned char *,int,int);
76 extern int fh_png_id(char *);
77 #endif
79 void init_handlers(void)
81 #ifdef FBV_SUPPORT_GIF
82 add_format(fh_gif_getsize,fh_gif_load,fh_gif_id);
83 #endif
84 #ifdef FBV_SUPPORT_JPEG
85 add_format(fh_jpeg_getsize,fh_jpeg_load,fh_jpeg_id);
86 #endif
87 #ifdef FBV_SUPPORT_PNG
88 add_format(fh_png_getsize,fh_png_load,fh_png_id);
89 #endif
92 struct formathandler * fh_getsize(char *name,int *x,int *y)
94 struct formathandler *fh;
95 for(fh=fh_root;fh!=NULL;fh=fh->next)
97 if(fh->id_pic(name))
98 if(fh->get_size(name,x,y)==FH_ERROR_OK) return(fh);
100 return(NULL);
103 int show_image(char *name)
105 int x,y,xs,ys,xpos,ypos,xdelta,ydelta,c,eol,xstep,ystep,rfrsh,imx,imy;
106 unsigned char *buffer;
107 struct formathandler *fh;
108 eol=1;
109 if(fh=fh_getsize(name,&x,&y))
111 buffer=(unsigned char *) malloc(x*y*3);
112 if(fh->get_pic(name,buffer,x,y)==FH_ERROR_OK)
114 if(clear) { printf("\033[H\033[J"); fflush(stdout); usleep(SHOWDELAY); } /* temporary solution */
115 if(dispinfo) printf("%s\n%s\n%d x %d\n",IDSTRING,name,x,y);
116 contoraw();
117 getCurrentRes(&xs,&ys);
118 if((x>xs || y>ys) && allowstrech)
120 if( (y*xs/x) <= ys)
122 imx=xs;
123 imy=y*xs/x;
125 else
127 imx=x*ys/y;
128 imy=ys;
130 if(allowstrech==1)
131 buffer=simple_resize(buffer,x,y,imx,imy);
132 else
133 buffer=color_average_resize(buffer,x,y,imx,imy);
134 x=imx; y=imy;
137 if(x<xs) xpos=(xs-x)/2; else xpos=0;
138 if(y<ys) ypos=(ys-y)/2; else ypos=0;
139 xdelta=0; ydelta=0;
141 xstep=min(max(x/20,1),xs);
142 ystep=min(max(y/20,1),ys);
144 for(eol=-1,rfrsh=1;eol==-1;)
146 if(rfrsh) fb_display(buffer,x,y,xdelta,ydelta,xpos,ypos);
147 rfrsh=0;
148 if(!delay)
150 c=getchar();
151 switch(c)
153 case 'a': case 'D':
154 xdelta-=xstep;
155 if(xdelta<0) xdelta=0;
156 rfrsh=1;
157 break;
158 case 'd': case 'C':
159 if(xpos) break;
160 xdelta+=xstep;
161 if(xdelta>(x-xs)) xdelta=x-xs;
162 rfrsh=1;
163 break;
164 case 'w': case 'A':
165 ydelta-=ystep;
166 if(ydelta<0) ydelta=0;
167 rfrsh=1;
168 break;
169 case 'x': case 'B':
170 if(ypos) break;
171 ydelta+=ystep;
172 if(ydelta>(y-ys)) ydelta=y-ys;
173 rfrsh=1;
174 break;
175 case ' ': case 10: eol=1; break;
176 case 'r': rfrsh=1; break;
177 case '.': case '>': eol=NEXT_IMG; break;
178 case ',': case '<': case 127: case 255: eol=PREV_IMG; break;
179 case 'q': eol=0; break;
182 else
184 if(imm_getchar(delay / 10,delay % 10)=='q') eol=0; else eol=1;
185 break;
188 connorm();
189 if(clear) { printf("\033[0m\033[H\033[J"); fflush(stdout); }
191 else
192 printf("Unable to read file !\n");
193 free(buffer);
195 else
196 printf("Unable to read file or format not recognized!\n");
198 return(eol);
201 void help(char *name)
203 printf("Usage: %s [options] image1 image2 image3 ...\n\n"
204 "The options are:\n"
205 " -h : Show this help\n"
206 " -c : Do not clear the screen before/after displaying image\n"
207 " -u : Do not hide/show cursor before/after displaying image\n"
208 " -i : Do not show image information\n"
209 " -f : Strech (using simple resize) the image to fit onto screen if necessary\n"
210 " -k : Strech (using color average resize) the image to fit onto screen if necessary\n"
211 " -s <delay> slideshow, wait 'delay' tenths of a second before displaying each image\n\n"
212 "Use a,d,w and x to scroll the image\n\n"
213 "%s/2000, http://s-tech.linux-pl.com\n",name,IDSTRING);
216 extern int optind;
217 extern char *optarg;
219 int main(int argc,char **argv)
221 int x,y,opt,a,r;
222 unsigned char *buffer;
223 init_handlers();
225 if(argc<2)
226 help(argv[0]);
227 else
229 for(;;)
231 opt=getopt_long(argc,argv,"chukfis:");
232 if(opt==EOF) break;
233 switch(opt)
235 case 'c': clear=0; break;
236 case 's': if(optarg) delay=atoi(optarg); break;
237 case 'u': hide=0; break;
238 case 'h': help(argv[0]); break;
239 case 'i': dispinfo=0; break;
240 case 'f': allowstrech=1; break;
241 case 'k': allowstrech=2; break;
244 while(imm_getchar(0,0)!=EOF);
245 if(hide) printf("\033[?25l");
246 for(a=optind;argv[a]!=NULL;a++)
248 r=show_image(argv[a]);
249 if(!r) break;
250 if(r==PREV_IMG)
251 if((a-1)>=optind)
252 a-=2;
253 else
254 a-=1;
256 if(hide) printf("\033[?25h");
258 return;