Date:2010-10-20 04:13:18 (10 years 9 hours ago)
Author:Xiangfu Liu
Commit:16ccc7f946243b7f8edc0733b43258636dfdd372
Message:some improvements to imgv

- zooming the image keeps the center at the same place
- if the image is smaller than the screen it is centered
- zooming a rotated image keeps the rotation
- the current path and file name is displayed above the image (can be hidden
with "d")
- you can add more than one image file as parameter (run "imgv a.jpg b.jpg
*.png" and cycle through them by pressing "n" or "p")
- start / stop slideshow by pressing "s" (will load the next image after 5
seconds)

According to the TODO file, Niels would call this version 0.3.0.

If you want to use it on one of the newer OpenWrt images with uclibc-0.9.32
you have to link it against libpthread (so add "-lpthread" the the LIBS
variable in the Makefile).

Niels
Files: Makefile (1 diff)
sdl-imageviewer.c (1 diff)

Change Details

Makefile
55
66####### Compiler, tools and options
77
8CC = mipsel-openwrt-linux-uclibc-gcc
9STRIP = mipsel-openwrt-linux-uclibc-strip
8CC ?= mipsel-openwrt-linux-uclibc-gcc
9STRIP ?= mipsel-openwrt-linux-uclibc-strip
1010CFLAGS := $(CFLAGS) -pipe -O2 -fomit-frame-pointer -mips32 -mtune=mips32 -funit-at-a-time -fhonour-copts -msoft-float -Wall -W -D_REENTRANT
1111INCPATH = -I$(TARGETPATH)/usr/include/ -I$(TARGETPATH)/usr/include/SDL -I.
12LIBS = -L$(TARGETPATH)/usr/lib/ -lSDL -lSDL_image -lSDL_gfx -ldirectfb -ldirect -lfusion -lz
12LIBS = -L$(TARGETPATH)/usr/lib/ -lSDL -lSDL_image -lSDL_gfx -ldirectfb -ldirect -lfusion -lz -lpthread
1313
1414SOURCE1 = sdl-imageviewer.c
1515TARGET1 = imgv
sdl-imageviewer.c
11// imgv, a simple SDL-based image viewer for the Ben Nanonote
2// Version 0.2.1
2// Version 0.3.0
33// Last edited by Fernando Carello <fcarello@libero.it> 2010-05-24
4// Last edited by Niels Kummerfeldt <niels.kummerfeldt@tuhh.de> 2010-10-19
45//
56#include <stdlib.h>
67#include <unistd.h>
78#include <SDL/SDL.h>
89#include <SDL/SDL_image.h>
910#include <SDL/SDL_rotozoom.h>
11#include <SDL/SDL_ttf.h>
1012
1113#define TRUE 1
1214#define FALSE 0
1315#define SCREENWIDTH 320
1416#define SCREENHEIGHT 240
1517#define SCREENBPP 32
16#define SMOOTHING_OFF 0
17#define SMOOTHING_ON 1
18#define SMOOTHING_OFF 0
19#define SMOOTHING_ON 1
1820#define PANSTEP 40
19#define ZOOMSTEP 0.05
21#define ZOOMSTEP 1.2
22#define SLIDESHOWTIMEOUT 1000 * 5
23#define VERSION "0.3.0"
24
25void quit()
26{
27    TTF_Quit();
28    SDL_Quit();
29
30    exit(1);
31}
32
33SDL_Surface *initScreen()
34{
35    // Initialize the SDL library
36    if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) < 0)
37    {
38        fprintf(stderr, "\n Couldn't initialize SDL: %s\n\n", SDL_GetError());
39        quit();
40    }
41
42    // Set video mode
43    SDL_Surface *screen = SDL_SetVideoMode(SCREENWIDTH, SCREENHEIGHT, SCREENBPP,
44                                           SDL_DOUBLEBUF | SDL_HWSURFACE | SDL_HWACCEL);
45    if (screen == (SDL_Surface *) (NULL))
46    {
47        fprintf(stderr, "Couldn't set %dx%dx%d video mode: %s\n\n", SCREENWIDTH, SCREENHEIGHT, SCREENBPP, SDL_GetError());
48        quit();
49    }
50
51    // Can't stand the useless arrow... Ben has no pointing device
52    SDL_ShowCursor(SDL_DISABLE);
53
54    TTF_Init();
55
56    return screen;
57}
58
59SDL_Surface *loadImage(char *filename)
60{
61    // Load Picture
62    SDL_Surface *tmp = IMG_Load(filename);
63    if (tmp == (SDL_Surface *) (NULL))
64    {
65        fprintf(stderr, "\n Couldn't load image file %s: %s\n\n", filename, SDL_GetError());
66        quit();
67    }
68
69    // Auto rotate image to fit screen
70    //if (tmp->w > SCREENWIDTH || tmp->h > SCREENHEIGHT) {
71    // if (tmp->h > tmp->w * 1.1) {
72    // SDL_Surface *t = rotateSurface90Degrees(tmp, 3);
73    // SDL_FreeSurface(tmp);
74    // tmp = t;
75    // }
76    //}
77
78    // Convert picture in same format as video framebuffer, to optimize blit performances
79    SDL_Surface *picture = SDL_DisplayFormat(tmp);
80    if (picture == (SDL_Surface *) (NULL))
81    {
82        fprintf(stderr, "\n Internal error from DisplayFormat\n\n");
83        quit();
84    }
85    SDL_FreeSurface(tmp);
86
87    return picture;
88}
89
90void pan(SDL_Surface *image, SDL_Rect *pos, int dx, int dy)
91{
92    if (image->w > SCREENWIDTH) {
93        pos->x += dx;
94        if (pos->x < 0) {
95            pos->x = 0;
96        }
97        if (pos->x >= image->w - SCREENWIDTH) {
98            pos->x = (Sint16) (image->w - SCREENWIDTH);
99        }
100    } else {
101        pos->x = 0;
102    }
103    if (image->h > SCREENHEIGHT) {
104        pos->y += dy;
105        if (pos->y < 0) {
106            pos->y = 0;
107        }
108        if (pos->y >= image->h - SCREENHEIGHT) {
109            pos->y = (Sint16) (image->h - SCREENHEIGHT);
110        }
111    } else {
112        pos->y = 0;
113    }
114}
115
116SDL_Surface *zoomIn(SDL_Surface *image, SDL_Rect *pos, double *scale)
117{
118    *scale *= ZOOMSTEP;
119
120    SDL_Surface *result = zoomSurface(image, *scale, *scale, SMOOTHING_ON);
121    if (result == (SDL_Surface *) (NULL))
122    {
123        fprintf(stderr, "\n Error from zoomSurface()\n\n");
124        quit();
125    }
126
127    pos->x *= ZOOMSTEP;
128    int dx = SCREENWIDTH * (ZOOMSTEP-1) * 0.5;
129    pos->y *= ZOOMSTEP;
130    int dy = SCREENHEIGHT * (ZOOMSTEP-1) * 0.5;
131    pan(result, pos, dx, dy);
132
133    return result;
134}
135
136SDL_Surface *zoomOut(SDL_Surface *image, SDL_Rect *pos, double *scale)
137{
138    *scale /= ZOOMSTEP;
139
140    SDL_Surface *result = zoomSurface(image, *scale, *scale, SMOOTHING_ON);
141    if (result == (SDL_Surface *) (NULL))
142    {
143        fprintf(stderr, "\n Error from zoomSurface()\n\n");
144        quit();
145    }
146
147    pos->x += SCREENWIDTH * (1-ZOOMSTEP) * 0.5;
148    pos->x /= ZOOMSTEP;
149    pos->y += SCREENHEIGHT * (1-ZOOMSTEP) * 0.5;
150    pos->y /= ZOOMSTEP;
151    pan(result, pos, 0, 0);
152
153    return result;
154}
155
156SDL_Surface *zoomFit(SDL_Surface *image, SDL_Rect *pos, double *scale)
157{
158    pos->x = 0;
159    pos->y = 0;
160    double scale_x = (double) (SCREENWIDTH) / (double) (image->w);
161    double scale_y = (double) (SCREENHEIGHT) / (double) (image->h);
162    if (scale_y < scale_x) {
163        *scale = scale_y;
164    } else {
165        *scale = scale_x;
166    }
167
168    SDL_Surface *result = zoomSurface(image, *scale, *scale, SMOOTHING_ON);
169    if (result == (SDL_Surface *) (NULL))
170    {
171        fprintf(stderr, "\n Error from zoomSurface()\n\n");
172        quit();
173    }
174
175    return result;
176}
177
178SDL_Surface *zoom100(SDL_Surface *image, SDL_Rect *pos, double *scale)
179{
180    SDL_Surface *result = SDL_ConvertSurface(image, image->format, image->flags);
181    if (result == (SDL_Surface *) (NULL))
182    {
183        fprintf(stderr, "\n Error from ConvertSurface()\n\n");
184        quit();
185    }
186
187    if (*scale < 1.0) {
188        pos->x /= *scale;
189        pos->y /= *scale;
190        pos->x -= SCREENWIDTH * (1-(1 / *scale)) * 0.5;
191        pos->y -= SCREENHEIGHT * (1-(1 / *scale)) * 0.5;
192    } else {
193        pos->x += SCREENWIDTH * (1-*scale) * 0.5;
194        pos->y += SCREENHEIGHT * (1-*scale) * 0.5;
195        pos->x /= *scale;
196        pos->y /= *scale;
197    }
198    pan(result, pos, 0, 0);
199    *scale = 1.0;
200
201    return result;
202}
203
204SDL_Surface *drawFileName(char *filename, TTF_Font *font, int slideShow)
205{
206    if(font) {
207        SDL_Color foregroundColor = { 0, 0, 0, 0 };
208        SDL_Color backgroundColor = { 200, 200, 200, 0 };
209
210        char text[strlen(filename)+4];
211        strcpy(text, filename);
212        if (slideShow) {
213            strcat(text, " >>");
214        }
215        return TTF_RenderText_Shaded(font, text, foregroundColor, backgroundColor);
216    }
217    return NULL;
218}
219
220void drawImage(SDL_Surface *image, SDL_Rect *pos, SDL_Surface *screen, SDL_Surface *filename)
221{
222    SDL_FillRect(screen, (SDL_Rect *) NULL, 0); // draw background color (black)
223
224    SDL_Rect screenPos;
225    if (image->w < SCREENWIDTH) {
226        screenPos.x = (SCREENWIDTH - image->w) / 2;
227    } else {
228        screenPos.x = 0;
229    }
230    if (image->h < SCREENHEIGHT) {
231        screenPos.y = (SCREENHEIGHT - image->h) / 2;
232    } else {
233        screenPos.y = 0;
234    }
235    SDL_BlitSurface(image, pos, screen, &screenPos);
236
237    if(filename) {
238        SDL_Rect textLocation = { 0, 0, 0, 0 };
239        if (filename->w > SCREENWIDTH) {
240            textLocation.x = SCREENWIDTH - filename->w;
241        }
242        SDL_BlitSurface(filename, NULL, screen, &textLocation);
243    }
244
245    SDL_Flip(screen);
246}
247
248Uint32 timerCallback(Uint32 interval, void *param)
249{
250    param = NULL;
251    SDL_Event event;
252    SDL_KeyboardEvent keyEvent;
253
254    keyEvent.type = SDL_KEYDOWN;
255    keyEvent.keysym.unicode = 0;
256    keyEvent.keysym.scancode = 0;
257    keyEvent.keysym.mod = 0;
258    keyEvent.keysym.sym = SDLK_n;
259
260    event.type = SDL_KEYDOWN;
261    event.key = keyEvent;
262
263    SDL_PushEvent(&event);
264
265    return interval;
266}
20267
21268int main(int argc, char *argv[])
22269{
23    SDL_Surface *screen = NULL,
24                *scaled_img = NULL,
25                *temp_img = NULL,
26                 *picture = NULL;
27    SDL_Event event;
28    SDL_Rect picturePortion,
29                screenPortion;
30    int imgWidth,
31                imgHeight,
32                smoothing = SMOOTHING_ON,
33                fPressed,
34                zPressed,
35                iPressed,
36                oPressed,
37                alreadyFit,
38                pixelFit,
39                lPressed,
40                rPressed,
41                leftPressed,
42                rightPressed,
43                upPressed,
44                downPressed;
45    char * sFilename;
46    char sVersion[] = "0.2.1";
47    double scale_x = 1.0,
48                scale_y = 1.0,
49                scale = 1.0;
50
51
52    atexit(SDL_Quit);
53
54    // Process command line
55    if (argc != 2)
56    {
57        fprintf (stderr, "\n"
58             " imgv v%s. Syntax: imgv <image file>\n\n"
59             " Hotkeys:\n"
60             " 'f' fit to screen\n"
61             " 'z' zoom at pixel level\n"
62             " 'i' zoom in 'o' zoom out\n"
63             " 'l' rotate left 'r' rotate right\n"
64             " 'arrows' pan 'ESC' quit\n\n", sVersion);
65        exit (1);
66    }
67    sFilename = argv[1];
68
69    // Initialize the SDL library
70    if (SDL_Init(SDL_INIT_VIDEO) < 0)
71    {
72        fprintf(stderr, "\n Couldn't initialize SDL: %s\n\n", SDL_GetError());
73        exit(1);
74    }
75
76    // Load Picture
77    temp_img = IMG_Load(sFilename);
78    if (temp_img == (SDL_Surface *) (NULL))
79    {
80        fprintf(stderr, "\n Couldn't load image file %s: %s\n\n", sFilename, SDL_GetError());
81        exit (1);
82    }
83
84    // Set video mode
85    screen = SDL_SetVideoMode
86        (SCREENWIDTH, SCREENHEIGHT, SCREENBPP, SDL_DOUBLEBUF | SDL_HWSURFACE | SDL_HWACCEL);
87    if (screen == (SDL_Surface *) (NULL))
88    {
89        fprintf(stderr, "Couldn't set %dx%dx%d video mode: %s\n\n", SCREENWIDTH, SCREENHEIGHT, SCREENBPP, SDL_GetError());
90        exit(1);
91    }
92
93    // Can't stand the useless arrow... Ben has no pointing device
94    SDL_ShowCursor(SDL_DISABLE);
95
96    // Convert picture in same format as video framebuffer, to optimize blit performances
97    picture = SDL_DisplayFormat (temp_img);
98    if (picture == (SDL_Surface *) (NULL))
99    {
100        fprintf(stderr, "\n Internal error from DisplayFormat\n\n");
101        exit (1);
102    }
103    SDL_FreeSurface (temp_img);
104
105    imgWidth = picture->w;
106    imgHeight = picture->h;
107
108    // Starting point (default view): uniform scaling to best screen fit, keep aspect ratio
109    scale_x = (double) (SCREENWIDTH) / (double) (imgWidth);
110    scale_y = (double) (SCREENHEIGHT) / (double) (imgHeight);
111    if (scale_y < scale_x)
112        scale = scale_y;
113    else
114        scale = scale_x;
115    scaled_img = zoomSurface (picture, scale, scale, SMOOTHING_ON);
116    if (scaled_img == (SDL_Surface *) (NULL))
117    {
118        fprintf (stderr, "\n Error from zoomSurface()\n\n");
119        exit (1);
120    }
121
122    screenPortion.x = 0; // destination coordinates: origin
123    screenPortion.y = 0;
124    picturePortion.x = 0;
125    picturePortion.y = 0;
126    picturePortion.w = (Uint16) imgWidth;
127    picturePortion.h = (Uint16) imgHeight;
128
129    // off-cycle: first image drawing
130    SDL_FillRect(screen, NULL, 0); // draw background color (black)
131    SDL_BlitSurface(scaled_img, &picturePortion, screen, &screenPortion);
132    SDL_Flip(screen);
133
134    leftPressed = FALSE;
135    rightPressed = FALSE;
136    upPressed = FALSE;
137    downPressed = FALSE;
138    fPressed = FALSE;
139    zPressed = FALSE;
140    lPressed = FALSE;
141    rPressed = FALSE;
142    iPressed = FALSE;
143    oPressed = FALSE;
144    pixelFit = FALSE;
145    alreadyFit = TRUE;
146
147    while(1)
148    {
149        if (SDL_WaitEvent( &event ))
150        {
151            // We only process SDL_KEYDOWN and SDL_KEYUP events
152            switch (event.type)
153            {
154                  case SDL_KEYDOWN:
155                      switch (event.key.keysym.sym)
156                    {
157                          case SDLK_LEFT:
158                              leftPressed = TRUE;
159                          break;
160                          case SDLK_RIGHT:
161                              rightPressed = TRUE;
162                          break;
163                          case SDLK_DOWN:
164                              downPressed = TRUE;
165                          break;
166                          case SDLK_f:
167                              fPressed = TRUE;
168                          break;
169                          case SDLK_z:
170                              zPressed = TRUE;
171                          break;
172                          case SDLK_i:
173                              iPressed = TRUE;
174                          break;
175                          case SDLK_o:
176                              oPressed = TRUE;
177                          break;
178                          case SDLK_l:
179                              lPressed = TRUE;
180                          break;
181                          case SDLK_r:
182                              rPressed = TRUE;
183                          break;
184                          case SDLK_UP:
185                              upPressed = TRUE;
186                          break;
187                          case SDLK_ESCAPE:
188                            if (picture)
189                                SDL_FreeSurface (picture);
190                            if (scaled_img)
191                                SDL_FreeSurface (scaled_img);
192                            if (screen)
193                                SDL_FreeSurface (screen);
194                              exit(0);
195                          default:
196                          break;
197                      }
198                  break;
199                 case SDL_KEYUP:
200                      switch (event.key.keysym.sym)
201                    {
202                          case SDLK_LEFT:
203                              leftPressed = FALSE;
204                          break;
205                          case SDLK_RIGHT:
206                              rightPressed = FALSE;
207                          break;
208                          case SDLK_DOWN:
209                              downPressed = FALSE;
210                          break;
211                          case SDLK_UP:
212                              upPressed = FALSE;
213                          break;
214                          case SDLK_f:
215                              fPressed = FALSE;
216                          break;
217                          case SDLK_z:
218                              zPressed = FALSE;
219                          break;
220                          case SDLK_i:
221                              iPressed = FALSE;
222                          break;
223                          case SDLK_o:
224                              oPressed = FALSE;
225                          break;
226                          case SDLK_l:
227                              lPressed = FALSE;
228                          break;
229                          case SDLK_r:
230                              rPressed = FALSE;
231                          break;
232                          default:
233                          break;
234                      }
235                  break;
236            } // end of switch (event.type)
237
238            // Process commands
239            if (fPressed && !alreadyFit)
240            { // Fit image to screen
241                if (scaled_img != (SDL_Surface *) (NULL))
242                    SDL_FreeSurface (scaled_img); // since zoomSurface() creates a new surface every time
243                alreadyFit = TRUE;
244                pixelFit = FALSE;
245                scale_x = (double) (SCREENWIDTH) / (double) (imgWidth);
246                scale_y = (double) (SCREENHEIGHT) / (double) (imgHeight);
247                if (scale_y < scale_x)
248                    scale = scale_y;
249                else
250                    scale = scale_x;
251                picturePortion.x = 0;
252                picturePortion.y = 0;
253                picturePortion.w = (Uint16) imgWidth;
254                picturePortion.h = (Uint16) imgHeight;
255                scaled_img = zoomSurface (picture, scale, scale, smoothing);
256                if (scaled_img == (SDL_Surface *) (NULL))
257                {
258                    fprintf (stderr, "\n Error from zoomSurface()\n\n");
259                    exit (1);
260                }
261            }
262            if (zPressed && !pixelFit)
263            { // Zoom at 1:1 (100% zoom / actual pixels)
264                if (scaled_img != (SDL_Surface *) (NULL))
265                    SDL_FreeSurface (scaled_img);
266                alreadyFit = FALSE;
267                pixelFit = TRUE;
268                picturePortion.w = (Uint16) SCREENWIDTH;
269                picturePortion.h = (Uint16) SCREENHEIGHT;
270                scale = 1.0;
271                scaled_img = SDL_ConvertSurface (picture, picture->format, picture->flags);
272                if (scaled_img == (SDL_Surface *) (NULL))
273                {
274                    fprintf (stderr, "\n Error from ConvertSurface()\n\n");
275                    exit (1);
276                }
277            }
278            if (iPressed)
279            { // Zoom in
280                if (scaled_img != (SDL_Surface *) (NULL))
281                    SDL_FreeSurface (scaled_img);
282                alreadyFit = FALSE;
283                pixelFit = FALSE;
284                scale += ZOOMSTEP;
285                picturePortion.w = (Uint16) ((double) (imgWidth) * scale);
286                if ( (picturePortion.w - picturePortion.x) >= imgWidth )
287                    picturePortion.w = imgWidth - picturePortion.x;
288                if (picturePortion.w < 1)
289                    picturePortion.w = 1;
290                picturePortion.h = (Uint16) ((double) (imgHeight) * scale);
291                if ( (picturePortion.h - picturePortion.y) >= imgHeight )
292                    picturePortion.h = imgHeight - picturePortion.y;
293                if (picturePortion.h < 1)
294                    picturePortion.h = 1;
295                scaled_img = zoomSurface (picture, scale, scale, smoothing);
296                //scaled_img = rotozoomSurface (picture, 0, scale, SMOOTHING_ON);
297
298                if (scaled_img == (SDL_Surface *) (NULL))
299                {
300                    fprintf (stderr, "\n Error from zoomSurface()\n\n");
301                    exit (1);
302                }
303            }
304            if (oPressed)
305            { // Zoom out
306                if (scaled_img != (SDL_Surface *) (NULL))
307                    SDL_FreeSurface (scaled_img);
308                alreadyFit = FALSE;
309                pixelFit = FALSE;
310                scale -= ZOOMSTEP;
311                if (scale <= 0.0)
312                    scale = 0.01;
313                picturePortion.w = (Uint16) ((double) (imgWidth) * scale);
314                if ( (picturePortion.w - picturePortion.x) >= imgWidth)
315                    picturePortion.w = imgWidth - picturePortion.x;
316                if (picturePortion.w < 1)
317                    picturePortion.w = 1;
318                picturePortion.h = (Uint16) ((double) (imgHeight) * scale);
319                if ( (picturePortion.h - picturePortion.y) >= imgHeight )
320                    picturePortion.h = imgHeight - picturePortion.y;
321                if (picturePortion.h < 1)
322                    picturePortion.h = 1;
323
324                scaled_img = zoomSurface (picture, scale, scale, smoothing);
325                //scaled_img = rotozoomSurface (picture, 0, scale, SMOOTHING_ON);
326                if (scaled_img == (SDL_Surface *) (NULL))
327                {
328                    fprintf (stderr, "\n Error from zoomSurface()\n\n");
329                    exit (1);
330                }
331            }
332
333            if (lPressed)
334            { // Rotate left 90°
335                if (scaled_img != (SDL_Surface *) (NULL))
336                    temp_img = scaled_img;
337                else
338                {
339                    fprintf (stderr, "\n Error: NULL scaled_img\n\n");
340                    exit (1);
341                }
342                alreadyFit = FALSE;
343                scaled_img = rotozoomSurface (temp_img, -90, 1.0, SMOOTHING_OFF);
344                SDL_FreeSurface (temp_img);
345                if (scaled_img == (SDL_Surface *) (NULL))
346                {
347                    fprintf (stderr, "\n Error from rotozoomSurface()\n\n");
348                    exit (1);
349                }
350            }
351            if (rPressed)
352            { // Rotate right 90°
353                if (scaled_img != (SDL_Surface *) (NULL))
354                    temp_img = scaled_img;
355                else
356                {
357                    fprintf (stderr, "\n Error: NULL scaled_img\n\n");
358                    exit (1);
359                }
360                alreadyFit = FALSE;
361                scaled_img = rotozoomSurface (temp_img, 90, 1.0, SMOOTHING_OFF);
362                SDL_FreeSurface (temp_img);
363                if (scaled_img == (SDL_Surface *) (NULL))
364                {
365                    fprintf (stderr, "\n Error from rotozoomSurface()\n\n");
366                    exit (1);
367                }
368            }
369
370            if (leftPressed)
371            {
372                picturePortion.x -= PANSTEP;
373                if (picturePortion.x < 0)
374                    picturePortion.x = 0;
375                alreadyFit = FALSE;
376            }
377            if (rightPressed)
378            {
379                picturePortion.x += PANSTEP;
380                if (picturePortion.x >= imgWidth)
381                    picturePortion.x = (Sint16) (imgWidth - 1);
382                alreadyFit = FALSE;
383            }
384            if (upPressed)
385            {
386                picturePortion.y -= PANSTEP;
387                if (picturePortion.y < 0)
388                    picturePortion.y = 0;
389                alreadyFit = FALSE;
390            }
391            if (downPressed)
392            {
393                picturePortion.y += PANSTEP;
394                if (picturePortion.y >= imgHeight)
395                    picturePortion.y = (Sint16) (imgHeight - 1);
396                alreadyFit = FALSE;
397            }
398
399            SDL_FillRect(screen, (SDL_Rect *) NULL, 0); // draw background color (black)
400            SDL_BlitSurface(scaled_img, &picturePortion, screen, &screenPortion);
401            SDL_Flip(screen);
402        } // end of if(SDL_WaitEvent())
403    } // end of while(1)
404
405    return 0;
270    SDL_Surface *screen = NULL,
271                *image = NULL,
272                *scaledImage = NULL,
273                *name = NULL;
274    SDL_Rect picturePortion;
275    TTF_Font *font = NULL;
276    double scale = 1.0;
277    int currentImageNumber = 1,
278                 showFileName = TRUE,
279                 runSlideShow = FALSE,
280                 isRunning = TRUE;
281    SDL_TimerID slideShowTimer = 0;
282
283    // Process command line
284    if (argc < 2) {
285        fprintf(stderr, "\n"
286            " imgv v%s. Syntax: imgv <image files>\n\n"
287            " Hotkeys:\n"
288            " 'f' fit to screen\n"
289            " 'z' zoom at pixel level\n"
290            " 'i' zoom in 'o' zoom out\n"
291            " 'l' rotate left 'r' rotate right\n"
292            " 'n' next image 'p' previous image\n"
293            " 'd' show / hide file name\n"
294            " 's' start / stop slide show\n"
295            " 'arrows' pan 'ESC' quit\n\n", VERSION);
296        exit(0);
297    }
298
299    screen = initScreen();
300
301    font = TTF_OpenFont("font.ttf", 11);
302    if (font == (TTF_Font *) (NULL)) {
303        font = TTF_OpenFont("/usr/share/imgv/font.ttf", 11);
304    }
305    if (font == (TTF_Font *) (NULL)) {
306        font = TTF_OpenFont("/usr/share/fonts/ttf-dejavu/DejaVuSans.ttf", 11);
307    }
308
309    picturePortion.w = SCREENWIDTH;
310    picturePortion.h = SCREENHEIGHT;
311
312    image = loadImage(argv[1]);
313    if (image->w < SCREENWIDTH && image->h < SCREENHEIGHT) {
314        scaledImage = zoom100(image, &picturePortion, &scale);
315    } else {
316        scaledImage = zoomFit(image, &picturePortion, &scale);
317    }
318    name = drawFileName(argv[currentImageNumber], font, runSlideShow);
319    drawImage(scaledImage, &picturePortion, screen, name);
320
321    do {
322        SDL_Event event;
323        if (SDL_WaitEvent(&event) && event.type == SDL_KEYDOWN) {
324            switch (event.key.keysym.sym) {
325                case SDLK_LEFT: // PAN LEFT
326                    pan(scaledImage, &picturePortion, -PANSTEP, 0);
327                    break;
328                case SDLK_RIGHT: // PAN RIGHT
329                    pan(scaledImage, &picturePortion, PANSTEP, 0);
330                    break;
331                case SDLK_UP: // PAN UP
332                    pan(scaledImage, &picturePortion, 0, -PANSTEP);
333                    break;
334                case SDLK_DOWN: // PAN DOWN
335                    pan(scaledImage, &picturePortion, 0, PANSTEP);
336                    break;
337                case SDLK_i: // ZOOM IN
338                    SDL_FreeSurface(scaledImage);
339                    scaledImage = zoomIn(image, &picturePortion, &scale);
340                    break;
341                case SDLK_o: // ZOOM OUT
342                    SDL_FreeSurface(scaledImage);
343                    scaledImage = zoomOut(image, &picturePortion, &scale);
344                    break;
345                case SDLK_f: // ZOOM TO FIT SCREEN
346                    SDL_FreeSurface(scaledImage);
347                    scaledImage = zoomFit(image, &picturePortion, &scale);
348                    break;
349                case SDLK_z: // ZOOM TO ORIGINAL SIZE
350                    SDL_FreeSurface(scaledImage);
351                    scaledImage = zoom100(image, &picturePortion, &scale);
352                    break;
353                case SDLK_l: // ROTATE LEFT
354                    {
355                        SDL_FreeSurface(scaledImage);
356                        SDL_Surface *tmp = rotateSurface90Degrees(image, 3);
357                        SDL_FreeSurface(image);
358                        image = tmp;
359                        scaledImage = zoomSurface(image, scale, scale, SMOOTHING_ON);
360                        int x = picturePortion.x;
361                        picturePortion.x = picturePortion.y + SCREENHEIGHT/2 - SCREENWIDTH/2;
362                        picturePortion.y = scaledImage->h - x - SCREENHEIGHT/2 - SCREENWIDTH/2;
363                        pan(scaledImage, &picturePortion, 0, 0);
364                    }
365                    break;
366                case SDLK_r: // ROTATE RIGHT
367                    {
368                        SDL_FreeSurface(scaledImage);
369                        SDL_Surface *tmp = rotateSurface90Degrees(image, 1);
370                        SDL_FreeSurface(image);
371                        image = tmp;
372                        scaledImage = zoomSurface(image, scale, scale, SMOOTHING_ON);
373                        int x = picturePortion.x;
374                        picturePortion.x = scaledImage->w - picturePortion.y - SCREENWIDTH/2
375                                           - SCREENHEIGHT/2;
376                        picturePortion.y = x + SCREENWIDTH/2 - SCREENHEIGHT/2;
377                        pan(scaledImage, &picturePortion, 0, 0);
378                    }
379                    break;
380                case SDLK_n: // NEXT IMAGE
381                    if (currentImageNumber < argc-1) {
382                        ++currentImageNumber;
383
384                        SDL_FreeSurface(image);
385                        SDL_FreeSurface(scaledImage);
386                        SDL_FreeSurface(name);
387
388                        image = loadImage(argv[currentImageNumber]);
389                        if (image->w < SCREENWIDTH && image->h < SCREENHEIGHT) {
390                            scaledImage = zoom100(image, &picturePortion, &scale);
391                        } else {
392                            scaledImage = zoomFit(image, &picturePortion, &scale);
393                        }
394                        name = drawFileName(argv[currentImageNumber], font, runSlideShow);
395                    } else {
396                        if (runSlideShow) {
397                            SDL_RemoveTimer(slideShowTimer);
398                            runSlideShow = FALSE;
399                            name = drawFileName(argv[currentImageNumber], font, runSlideShow);
400                        }
401                    }
402                    break;
403                case SDLK_p: // PREVIOUS IMAGE
404                    if (currentImageNumber > 1) {
405                        --currentImageNumber;
406
407                        SDL_FreeSurface(image);
408                        SDL_FreeSurface(scaledImage);
409                        SDL_FreeSurface(name);
410
411                        image = loadImage(argv[currentImageNumber]);
412                        if (image->w < SCREENWIDTH && image->h < SCREENHEIGHT) {
413                            scaledImage = zoom100(image, &picturePortion, &scale);
414                        } else {
415                            scaledImage = zoomFit(image, &picturePortion, &scale);
416                        }
417                        name = drawFileName(argv[currentImageNumber], font, runSlideShow);
418                    }
419                    break;
420                case SDLK_s: // START / STOP SLIDESHOW
421                    runSlideShow = 1 - runSlideShow;
422                    name = drawFileName(argv[currentImageNumber], font, runSlideShow);
423                    if (runSlideShow) {
424                        slideShowTimer = SDL_AddTimer(SLIDESHOWTIMEOUT, timerCallback, NULL);
425                    } else {
426                        SDL_RemoveTimer(slideShowTimer);
427                    }
428                    break;
429                case SDLK_d: // SHOW / HIDE FILENAME
430                    showFileName = 1 - showFileName;
431                    break;
432                case SDLK_ESCAPE: // QUIT
433                case SDLK_q:
434                    isRunning = FALSE;
435                    break;
436                default:
437                    break;
438             } // end of switch (event.key.keysym.sym)
439        } // end of if(SDL_WaitEvent())
440        drawImage(scaledImage, &picturePortion, screen, showFileName ? name : 0);
441    } while(isRunning); // end of do
442
443    SDL_FreeSurface(image);
444    SDL_FreeSurface(scaledImage);
445    SDL_FreeSurface(screen);
446
447    TTF_CloseFont(font);
448    TTF_Quit();
449
450    SDL_Quit();
451
452    return 0;
406453}
407454

Archive Download the corresponding diff file

Branches:
master



interactive