1
0
mirror of git://projects.qi-hardware.com/imgv.git synced 2024-11-27 16:56:15 +02:00

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
This commit is contained in:
Xiangfu Liu 2010-10-20 10:13:18 +08:00
parent 0db77db043
commit 16ccc7f946
2 changed files with 423 additions and 376 deletions

View File

@ -5,11 +5,11 @@ TARGETPATH ?= $(BASEPATH)/staging_dir/target-mipsel_uClibc-0.9.30.1
####### Compiler, tools and options ####### Compiler, tools and options
CC = mipsel-openwrt-linux-uclibc-gcc CC ?= mipsel-openwrt-linux-uclibc-gcc
STRIP = mipsel-openwrt-linux-uclibc-strip STRIP ?= mipsel-openwrt-linux-uclibc-strip
CFLAGS := $(CFLAGS) -pipe -O2 -fomit-frame-pointer -mips32 -mtune=mips32 -funit-at-a-time -fhonour-copts -msoft-float -Wall -W -D_REENTRANT CFLAGS := $(CFLAGS) -pipe -O2 -fomit-frame-pointer -mips32 -mtune=mips32 -funit-at-a-time -fhonour-copts -msoft-float -Wall -W -D_REENTRANT
INCPATH = -I$(TARGETPATH)/usr/include/ -I$(TARGETPATH)/usr/include/SDL -I. INCPATH = -I$(TARGETPATH)/usr/include/ -I$(TARGETPATH)/usr/include/SDL -I.
LIBS = -L$(TARGETPATH)/usr/lib/ -lSDL -lSDL_image -lSDL_gfx -ldirectfb -ldirect -lfusion -lz LIBS = -L$(TARGETPATH)/usr/lib/ -lSDL -lSDL_image -lSDL_gfx -ldirectfb -ldirect -lfusion -lz -lpthread
SOURCE1 = sdl-imageviewer.c SOURCE1 = sdl-imageviewer.c
TARGET1 = imgv TARGET1 = imgv

View File

@ -1,12 +1,14 @@
// imgv, a simple SDL-based image viewer for the Ben Nanonote // imgv, a simple SDL-based image viewer for the Ben Nanonote
// Version 0.2.1 // Version 0.3.0
// Last edited by Fernando Carello <fcarello@libero.it> 2010-05-24 // Last edited by Fernando Carello <fcarello@libero.it> 2010-05-24
// Last edited by Niels Kummerfeldt <niels.kummerfeldt@tuhh.de> 2010-10-19
// //
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h> #include <unistd.h>
#include <SDL/SDL.h> #include <SDL/SDL.h>
#include <SDL/SDL_image.h> #include <SDL/SDL_image.h>
#include <SDL/SDL_rotozoom.h> #include <SDL/SDL_rotozoom.h>
#include <SDL/SDL_ttf.h>
#define TRUE 1 #define TRUE 1
#define FALSE 0 #define FALSE 0
@ -16,391 +18,436 @@
#define SMOOTHING_OFF 0 #define SMOOTHING_OFF 0
#define SMOOTHING_ON 1 #define SMOOTHING_ON 1
#define PANSTEP 40 #define PANSTEP 40
#define ZOOMSTEP 0.05 #define ZOOMSTEP 1.2
#define SLIDESHOWTIMEOUT 1000 * 5
#define VERSION "0.3.0"
int main(int argc, char *argv[]) void quit()
{ {
SDL_Surface *screen = NULL, TTF_Quit();
*scaled_img = NULL, SDL_Quit();
*temp_img = NULL,
*picture = NULL;
SDL_Event event;
SDL_Rect picturePortion,
screenPortion;
int imgWidth,
imgHeight,
smoothing = SMOOTHING_ON,
fPressed,
zPressed,
iPressed,
oPressed,
alreadyFit,
pixelFit,
lPressed,
rPressed,
leftPressed,
rightPressed,
upPressed,
downPressed;
char * sFilename;
char sVersion[] = "0.2.1";
double scale_x = 1.0,
scale_y = 1.0,
scale = 1.0;
exit(1);
}
atexit(SDL_Quit); SDL_Surface *initScreen()
{
// Process command line
if (argc != 2)
{
fprintf (stderr, "\n"
" imgv v%s. Syntax: imgv <image file>\n\n"
" Hotkeys:\n"
" 'f' fit to screen\n"
" 'z' zoom at pixel level\n"
" 'i' zoom in 'o' zoom out\n"
" 'l' rotate left 'r' rotate right\n"
" 'arrows' pan 'ESC' quit\n\n", sVersion);
exit (1);
}
sFilename = argv[1];
// Initialize the SDL library // Initialize the SDL library
if (SDL_Init(SDL_INIT_VIDEO) < 0) if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) < 0)
{ {
fprintf(stderr, "\n Couldn't initialize SDL: %s\n\n", SDL_GetError()); fprintf(stderr, "\n Couldn't initialize SDL: %s\n\n", SDL_GetError());
exit(1); quit();
}
// Load Picture
temp_img = IMG_Load(sFilename);
if (temp_img == (SDL_Surface *) (NULL))
{
fprintf(stderr, "\n Couldn't load image file %s: %s\n\n", sFilename, SDL_GetError());
exit (1);
} }
// Set video mode // Set video mode
screen = SDL_SetVideoMode SDL_Surface *screen = SDL_SetVideoMode(SCREENWIDTH, SCREENHEIGHT, SCREENBPP,
(SCREENWIDTH, SCREENHEIGHT, SCREENBPP, SDL_DOUBLEBUF | SDL_HWSURFACE | SDL_HWACCEL); SDL_DOUBLEBUF | SDL_HWSURFACE | SDL_HWACCEL);
if (screen == (SDL_Surface *) (NULL)) if (screen == (SDL_Surface *) (NULL))
{ {
fprintf(stderr, "Couldn't set %dx%dx%d video mode: %s\n\n", SCREENWIDTH, SCREENHEIGHT, SCREENBPP, SDL_GetError()); fprintf(stderr, "Couldn't set %dx%dx%d video mode: %s\n\n", SCREENWIDTH, SCREENHEIGHT, SCREENBPP, SDL_GetError());
exit(1); quit();
} }
// Can't stand the useless arrow... Ben has no pointing device // Can't stand the useless arrow... Ben has no pointing device
SDL_ShowCursor(SDL_DISABLE); SDL_ShowCursor(SDL_DISABLE);
TTF_Init();
return screen;
}
SDL_Surface *loadImage(char *filename)
{
// Load Picture
SDL_Surface *tmp = IMG_Load(filename);
if (tmp == (SDL_Surface *) (NULL))
{
fprintf(stderr, "\n Couldn't load image file %s: %s\n\n", filename, SDL_GetError());
quit();
}
// Auto rotate image to fit screen
//if (tmp->w > SCREENWIDTH || tmp->h > SCREENHEIGHT) {
// if (tmp->h > tmp->w * 1.1) {
// SDL_Surface *t = rotateSurface90Degrees(tmp, 3);
// SDL_FreeSurface(tmp);
// tmp = t;
// }
//}
// Convert picture in same format as video framebuffer, to optimize blit performances // Convert picture in same format as video framebuffer, to optimize blit performances
picture = SDL_DisplayFormat (temp_img); SDL_Surface *picture = SDL_DisplayFormat(tmp);
if (picture == (SDL_Surface *) (NULL)) if (picture == (SDL_Surface *) (NULL))
{ {
fprintf(stderr, "\n Internal error from DisplayFormat\n\n"); fprintf(stderr, "\n Internal error from DisplayFormat\n\n");
exit (1); quit();
} }
SDL_FreeSurface (temp_img); SDL_FreeSurface(tmp);
imgWidth = picture->w; return picture;
imgHeight = picture->h; }
// Starting point (default view): uniform scaling to best screen fit, keep aspect ratio void pan(SDL_Surface *image, SDL_Rect *pos, int dx, int dy)
scale_x = (double) (SCREENWIDTH) / (double) (imgWidth); {
scale_y = (double) (SCREENHEIGHT) / (double) (imgHeight); if (image->w > SCREENWIDTH) {
if (scale_y < scale_x) pos->x += dx;
scale = scale_y; if (pos->x < 0) {
else pos->x = 0;
scale = scale_x; }
scaled_img = zoomSurface (picture, scale, scale, SMOOTHING_ON); if (pos->x >= image->w - SCREENWIDTH) {
if (scaled_img == (SDL_Surface *) (NULL)) pos->x = (Sint16) (image->w - SCREENWIDTH);
}
} else {
pos->x = 0;
}
if (image->h > SCREENHEIGHT) {
pos->y += dy;
if (pos->y < 0) {
pos->y = 0;
}
if (pos->y >= image->h - SCREENHEIGHT) {
pos->y = (Sint16) (image->h - SCREENHEIGHT);
}
} else {
pos->y = 0;
}
}
SDL_Surface *zoomIn(SDL_Surface *image, SDL_Rect *pos, double *scale)
{
*scale *= ZOOMSTEP;
SDL_Surface *result = zoomSurface(image, *scale, *scale, SMOOTHING_ON);
if (result == (SDL_Surface *) (NULL))
{ {
fprintf (stderr, "\n Error from zoomSurface()\n\n"); fprintf(stderr, "\n Error from zoomSurface()\n\n");
exit (1); quit();
} }
screenPortion.x = 0; // destination coordinates: origin pos->x *= ZOOMSTEP;
screenPortion.y = 0; int dx = SCREENWIDTH * (ZOOMSTEP-1) * 0.5;
picturePortion.x = 0; pos->y *= ZOOMSTEP;
picturePortion.y = 0; int dy = SCREENHEIGHT * (ZOOMSTEP-1) * 0.5;
picturePortion.w = (Uint16) imgWidth; pan(result, pos, dx, dy);
picturePortion.h = (Uint16) imgHeight;
// off-cycle: first image drawing return result;
SDL_FillRect(screen, NULL, 0); // draw background color (black) }
SDL_BlitSurface(scaled_img, &picturePortion, screen, &screenPortion);
SDL_Flip(screen);
leftPressed = FALSE; SDL_Surface *zoomOut(SDL_Surface *image, SDL_Rect *pos, double *scale)
rightPressed = FALSE; {
upPressed = FALSE; *scale /= ZOOMSTEP;
downPressed = FALSE;
fPressed = FALSE;
zPressed = FALSE;
lPressed = FALSE;
rPressed = FALSE;
iPressed = FALSE;
oPressed = FALSE;
pixelFit = FALSE;
alreadyFit = TRUE;
while(1) SDL_Surface *result = zoomSurface(image, *scale, *scale, SMOOTHING_ON);
if (result == (SDL_Surface *) (NULL))
{ {
if (SDL_WaitEvent( &event )) fprintf(stderr, "\n Error from zoomSurface()\n\n");
{ quit();
// We only process SDL_KEYDOWN and SDL_KEYUP events
switch (event.type)
{
case SDL_KEYDOWN:
switch (event.key.keysym.sym)
{
case SDLK_LEFT:
leftPressed = TRUE;
break;
case SDLK_RIGHT:
rightPressed = TRUE;
break;
case SDLK_DOWN:
downPressed = TRUE;
break;
case SDLK_f:
fPressed = TRUE;
break;
case SDLK_z:
zPressed = TRUE;
break;
case SDLK_i:
iPressed = TRUE;
break;
case SDLK_o:
oPressed = TRUE;
break;
case SDLK_l:
lPressed = TRUE;
break;
case SDLK_r:
rPressed = TRUE;
break;
case SDLK_UP:
upPressed = TRUE;
break;
case SDLK_ESCAPE:
if (picture)
SDL_FreeSurface (picture);
if (scaled_img)
SDL_FreeSurface (scaled_img);
if (screen)
SDL_FreeSurface (screen);
exit(0);
default:
break;
}
break;
case SDL_KEYUP:
switch (event.key.keysym.sym)
{
case SDLK_LEFT:
leftPressed = FALSE;
break;
case SDLK_RIGHT:
rightPressed = FALSE;
break;
case SDLK_DOWN:
downPressed = FALSE;
break;
case SDLK_UP:
upPressed = FALSE;
break;
case SDLK_f:
fPressed = FALSE;
break;
case SDLK_z:
zPressed = FALSE;
break;
case SDLK_i:
iPressed = FALSE;
break;
case SDLK_o:
oPressed = FALSE;
break;
case SDLK_l:
lPressed = FALSE;
break;
case SDLK_r:
rPressed = FALSE;
break;
default:
break;
}
break;
} // end of switch (event.type)
// Process commands
if (fPressed && !alreadyFit)
{ // Fit image to screen
if (scaled_img != (SDL_Surface *) (NULL))
SDL_FreeSurface (scaled_img); // since zoomSurface() creates a new surface every time
alreadyFit = TRUE;
pixelFit = FALSE;
scale_x = (double) (SCREENWIDTH) / (double) (imgWidth);
scale_y = (double) (SCREENHEIGHT) / (double) (imgHeight);
if (scale_y < scale_x)
scale = scale_y;
else
scale = scale_x;
picturePortion.x = 0;
picturePortion.y = 0;
picturePortion.w = (Uint16) imgWidth;
picturePortion.h = (Uint16) imgHeight;
scaled_img = zoomSurface (picture, scale, scale, smoothing);
if (scaled_img == (SDL_Surface *) (NULL))
{
fprintf (stderr, "\n Error from zoomSurface()\n\n");
exit (1);
}
}
if (zPressed && !pixelFit)
{ // Zoom at 1:1 (100% zoom / actual pixels)
if (scaled_img != (SDL_Surface *) (NULL))
SDL_FreeSurface (scaled_img);
alreadyFit = FALSE;
pixelFit = TRUE;
picturePortion.w = (Uint16) SCREENWIDTH;
picturePortion.h = (Uint16) SCREENHEIGHT;
scale = 1.0;
scaled_img = SDL_ConvertSurface (picture, picture->format, picture->flags);
if (scaled_img == (SDL_Surface *) (NULL))
{
fprintf (stderr, "\n Error from ConvertSurface()\n\n");
exit (1);
}
}
if (iPressed)
{ // Zoom in
if (scaled_img != (SDL_Surface *) (NULL))
SDL_FreeSurface (scaled_img);
alreadyFit = FALSE;
pixelFit = FALSE;
scale += ZOOMSTEP;
picturePortion.w = (Uint16) ((double) (imgWidth) * scale);
if ( (picturePortion.w - picturePortion.x) >= imgWidth )
picturePortion.w = imgWidth - picturePortion.x;
if (picturePortion.w < 1)
picturePortion.w = 1;
picturePortion.h = (Uint16) ((double) (imgHeight) * scale);
if ( (picturePortion.h - picturePortion.y) >= imgHeight )
picturePortion.h = imgHeight - picturePortion.y;
if (picturePortion.h < 1)
picturePortion.h = 1;
scaled_img = zoomSurface (picture, scale, scale, smoothing);
//scaled_img = rotozoomSurface (picture, 0, scale, SMOOTHING_ON);
if (scaled_img == (SDL_Surface *) (NULL))
{
fprintf (stderr, "\n Error from zoomSurface()\n\n");
exit (1);
}
}
if (oPressed)
{ // Zoom out
if (scaled_img != (SDL_Surface *) (NULL))
SDL_FreeSurface (scaled_img);
alreadyFit = FALSE;
pixelFit = FALSE;
scale -= ZOOMSTEP;
if (scale <= 0.0)
scale = 0.01;
picturePortion.w = (Uint16) ((double) (imgWidth) * scale);
if ( (picturePortion.w - picturePortion.x) >= imgWidth)
picturePortion.w = imgWidth - picturePortion.x;
if (picturePortion.w < 1)
picturePortion.w = 1;
picturePortion.h = (Uint16) ((double) (imgHeight) * scale);
if ( (picturePortion.h - picturePortion.y) >= imgHeight )
picturePortion.h = imgHeight - picturePortion.y;
if (picturePortion.h < 1)
picturePortion.h = 1;
scaled_img = zoomSurface (picture, scale, scale, smoothing);
//scaled_img = rotozoomSurface (picture, 0, scale, SMOOTHING_ON);
if (scaled_img == (SDL_Surface *) (NULL))
{
fprintf (stderr, "\n Error from zoomSurface()\n\n");
exit (1);
}
} }
if (lPressed) pos->x += SCREENWIDTH * (1-ZOOMSTEP) * 0.5;
{ // Rotate left 90° pos->x /= ZOOMSTEP;
if (scaled_img != (SDL_Surface *) (NULL)) pos->y += SCREENHEIGHT * (1-ZOOMSTEP) * 0.5;
temp_img = scaled_img; pos->y /= ZOOMSTEP;
else pan(result, pos, 0, 0);
{
fprintf (stderr, "\n Error: NULL scaled_img\n\n"); return result;
exit (1); }
}
alreadyFit = FALSE; SDL_Surface *zoomFit(SDL_Surface *image, SDL_Rect *pos, double *scale)
scaled_img = rotozoomSurface (temp_img, -90, 1.0, SMOOTHING_OFF); {
SDL_FreeSurface (temp_img); pos->x = 0;
if (scaled_img == (SDL_Surface *) (NULL)) pos->y = 0;
{ double scale_x = (double) (SCREENWIDTH) / (double) (image->w);
fprintf (stderr, "\n Error from rotozoomSurface()\n\n"); double scale_y = (double) (SCREENHEIGHT) / (double) (image->h);
exit (1); if (scale_y < scale_x) {
} *scale = scale_y;
} } else {
if (rPressed) *scale = scale_x;
{ // Rotate right 90°
if (scaled_img != (SDL_Surface *) (NULL))
temp_img = scaled_img;
else
{
fprintf (stderr, "\n Error: NULL scaled_img\n\n");
exit (1);
}
alreadyFit = FALSE;
scaled_img = rotozoomSurface (temp_img, 90, 1.0, SMOOTHING_OFF);
SDL_FreeSurface (temp_img);
if (scaled_img == (SDL_Surface *) (NULL))
{
fprintf (stderr, "\n Error from rotozoomSurface()\n\n");
exit (1);
}
} }
if (leftPressed) SDL_Surface *result = zoomSurface(image, *scale, *scale, SMOOTHING_ON);
if (result == (SDL_Surface *) (NULL))
{ {
picturePortion.x -= PANSTEP; fprintf(stderr, "\n Error from zoomSurface()\n\n");
if (picturePortion.x < 0) quit();
picturePortion.x = 0;
alreadyFit = FALSE;
}
if (rightPressed)
{
picturePortion.x += PANSTEP;
if (picturePortion.x >= imgWidth)
picturePortion.x = (Sint16) (imgWidth - 1);
alreadyFit = FALSE;
}
if (upPressed)
{
picturePortion.y -= PANSTEP;
if (picturePortion.y < 0)
picturePortion.y = 0;
alreadyFit = FALSE;
}
if (downPressed)
{
picturePortion.y += PANSTEP;
if (picturePortion.y >= imgHeight)
picturePortion.y = (Sint16) (imgHeight - 1);
alreadyFit = FALSE;
} }
return result;
}
SDL_Surface *zoom100(SDL_Surface *image, SDL_Rect *pos, double *scale)
{
SDL_Surface *result = SDL_ConvertSurface(image, image->format, image->flags);
if (result == (SDL_Surface *) (NULL))
{
fprintf(stderr, "\n Error from ConvertSurface()\n\n");
quit();
}
if (*scale < 1.0) {
pos->x /= *scale;
pos->y /= *scale;
pos->x -= SCREENWIDTH * (1-(1 / *scale)) * 0.5;
pos->y -= SCREENHEIGHT * (1-(1 / *scale)) * 0.5;
} else {
pos->x += SCREENWIDTH * (1-*scale) * 0.5;
pos->y += SCREENHEIGHT * (1-*scale) * 0.5;
pos->x /= *scale;
pos->y /= *scale;
}
pan(result, pos, 0, 0);
*scale = 1.0;
return result;
}
SDL_Surface *drawFileName(char *filename, TTF_Font *font, int slideShow)
{
if(font) {
SDL_Color foregroundColor = { 0, 0, 0, 0 };
SDL_Color backgroundColor = { 200, 200, 200, 0 };
char text[strlen(filename)+4];
strcpy(text, filename);
if (slideShow) {
strcat(text, " >>");
}
return TTF_RenderText_Shaded(font, text, foregroundColor, backgroundColor);
}
return NULL;
}
void drawImage(SDL_Surface *image, SDL_Rect *pos, SDL_Surface *screen, SDL_Surface *filename)
{
SDL_FillRect(screen, (SDL_Rect *) NULL, 0); // draw background color (black) SDL_FillRect(screen, (SDL_Rect *) NULL, 0); // draw background color (black)
SDL_BlitSurface(scaled_img, &picturePortion, screen, &screenPortion);
SDL_Rect screenPos;
if (image->w < SCREENWIDTH) {
screenPos.x = (SCREENWIDTH - image->w) / 2;
} else {
screenPos.x = 0;
}
if (image->h < SCREENHEIGHT) {
screenPos.y = (SCREENHEIGHT - image->h) / 2;
} else {
screenPos.y = 0;
}
SDL_BlitSurface(image, pos, screen, &screenPos);
if(filename) {
SDL_Rect textLocation = { 0, 0, 0, 0 };
if (filename->w > SCREENWIDTH) {
textLocation.x = SCREENWIDTH - filename->w;
}
SDL_BlitSurface(filename, NULL, screen, &textLocation);
}
SDL_Flip(screen); SDL_Flip(screen);
}
Uint32 timerCallback(Uint32 interval, void *param)
{
param = NULL;
SDL_Event event;
SDL_KeyboardEvent keyEvent;
keyEvent.type = SDL_KEYDOWN;
keyEvent.keysym.unicode = 0;
keyEvent.keysym.scancode = 0;
keyEvent.keysym.mod = 0;
keyEvent.keysym.sym = SDLK_n;
event.type = SDL_KEYDOWN;
event.key = keyEvent;
SDL_PushEvent(&event);
return interval;
}
int main(int argc, char *argv[])
{
SDL_Surface *screen = NULL,
*image = NULL,
*scaledImage = NULL,
*name = NULL;
SDL_Rect picturePortion;
TTF_Font *font = NULL;
double scale = 1.0;
int currentImageNumber = 1,
showFileName = TRUE,
runSlideShow = FALSE,
isRunning = TRUE;
SDL_TimerID slideShowTimer = 0;
// Process command line
if (argc < 2) {
fprintf(stderr, "\n"
" imgv v%s. Syntax: imgv <image files>\n\n"
" Hotkeys:\n"
" 'f' fit to screen\n"
" 'z' zoom at pixel level\n"
" 'i' zoom in 'o' zoom out\n"
" 'l' rotate left 'r' rotate right\n"
" 'n' next image 'p' previous image\n"
" 'd' show / hide file name\n"
" 's' start / stop slide show\n"
" 'arrows' pan 'ESC' quit\n\n", VERSION);
exit(0);
}
screen = initScreen();
font = TTF_OpenFont("font.ttf", 11);
if (font == (TTF_Font *) (NULL)) {
font = TTF_OpenFont("/usr/share/imgv/font.ttf", 11);
}
if (font == (TTF_Font *) (NULL)) {
font = TTF_OpenFont("/usr/share/fonts/ttf-dejavu/DejaVuSans.ttf", 11);
}
picturePortion.w = SCREENWIDTH;
picturePortion.h = SCREENHEIGHT;
image = loadImage(argv[1]);
if (image->w < SCREENWIDTH && image->h < SCREENHEIGHT) {
scaledImage = zoom100(image, &picturePortion, &scale);
} else {
scaledImage = zoomFit(image, &picturePortion, &scale);
}
name = drawFileName(argv[currentImageNumber], font, runSlideShow);
drawImage(scaledImage, &picturePortion, screen, name);
do {
SDL_Event event;
if (SDL_WaitEvent(&event) && event.type == SDL_KEYDOWN) {
switch (event.key.keysym.sym) {
case SDLK_LEFT: // PAN LEFT
pan(scaledImage, &picturePortion, -PANSTEP, 0);
break;
case SDLK_RIGHT: // PAN RIGHT
pan(scaledImage, &picturePortion, PANSTEP, 0);
break;
case SDLK_UP: // PAN UP
pan(scaledImage, &picturePortion, 0, -PANSTEP);
break;
case SDLK_DOWN: // PAN DOWN
pan(scaledImage, &picturePortion, 0, PANSTEP);
break;
case SDLK_i: // ZOOM IN
SDL_FreeSurface(scaledImage);
scaledImage = zoomIn(image, &picturePortion, &scale);
break;
case SDLK_o: // ZOOM OUT
SDL_FreeSurface(scaledImage);
scaledImage = zoomOut(image, &picturePortion, &scale);
break;
case SDLK_f: // ZOOM TO FIT SCREEN
SDL_FreeSurface(scaledImage);
scaledImage = zoomFit(image, &picturePortion, &scale);
break;
case SDLK_z: // ZOOM TO ORIGINAL SIZE
SDL_FreeSurface(scaledImage);
scaledImage = zoom100(image, &picturePortion, &scale);
break;
case SDLK_l: // ROTATE LEFT
{
SDL_FreeSurface(scaledImage);
SDL_Surface *tmp = rotateSurface90Degrees(image, 3);
SDL_FreeSurface(image);
image = tmp;
scaledImage = zoomSurface(image, scale, scale, SMOOTHING_ON);
int x = picturePortion.x;
picturePortion.x = picturePortion.y + SCREENHEIGHT/2 - SCREENWIDTH/2;
picturePortion.y = scaledImage->h - x - SCREENHEIGHT/2 - SCREENWIDTH/2;
pan(scaledImage, &picturePortion, 0, 0);
}
break;
case SDLK_r: // ROTATE RIGHT
{
SDL_FreeSurface(scaledImage);
SDL_Surface *tmp = rotateSurface90Degrees(image, 1);
SDL_FreeSurface(image);
image = tmp;
scaledImage = zoomSurface(image, scale, scale, SMOOTHING_ON);
int x = picturePortion.x;
picturePortion.x = scaledImage->w - picturePortion.y - SCREENWIDTH/2
- SCREENHEIGHT/2;
picturePortion.y = x + SCREENWIDTH/2 - SCREENHEIGHT/2;
pan(scaledImage, &picturePortion, 0, 0);
}
break;
case SDLK_n: // NEXT IMAGE
if (currentImageNumber < argc-1) {
++currentImageNumber;
SDL_FreeSurface(image);
SDL_FreeSurface(scaledImage);
SDL_FreeSurface(name);
image = loadImage(argv[currentImageNumber]);
if (image->w < SCREENWIDTH && image->h < SCREENHEIGHT) {
scaledImage = zoom100(image, &picturePortion, &scale);
} else {
scaledImage = zoomFit(image, &picturePortion, &scale);
}
name = drawFileName(argv[currentImageNumber], font, runSlideShow);
} else {
if (runSlideShow) {
SDL_RemoveTimer(slideShowTimer);
runSlideShow = FALSE;
name = drawFileName(argv[currentImageNumber], font, runSlideShow);
}
}
break;
case SDLK_p: // PREVIOUS IMAGE
if (currentImageNumber > 1) {
--currentImageNumber;
SDL_FreeSurface(image);
SDL_FreeSurface(scaledImage);
SDL_FreeSurface(name);
image = loadImage(argv[currentImageNumber]);
if (image->w < SCREENWIDTH && image->h < SCREENHEIGHT) {
scaledImage = zoom100(image, &picturePortion, &scale);
} else {
scaledImage = zoomFit(image, &picturePortion, &scale);
}
name = drawFileName(argv[currentImageNumber], font, runSlideShow);
}
break;
case SDLK_s: // START / STOP SLIDESHOW
runSlideShow = 1 - runSlideShow;
name = drawFileName(argv[currentImageNumber], font, runSlideShow);
if (runSlideShow) {
slideShowTimer = SDL_AddTimer(SLIDESHOWTIMEOUT, timerCallback, NULL);
} else {
SDL_RemoveTimer(slideShowTimer);
}
break;
case SDLK_d: // SHOW / HIDE FILENAME
showFileName = 1 - showFileName;
break;
case SDLK_ESCAPE: // QUIT
case SDLK_q:
isRunning = FALSE;
break;
default:
break;
} // end of switch (event.key.keysym.sym)
} // end of if(SDL_WaitEvent()) } // end of if(SDL_WaitEvent())
} // end of while(1) drawImage(scaledImage, &picturePortion, screen, showFileName ? name : 0);
} while(isRunning); // end of do
SDL_FreeSurface(image);
SDL_FreeSurface(scaledImage);
SDL_FreeSurface(screen);
TTF_CloseFont(font);
TTF_Quit();
SDL_Quit();
return 0; return 0;
} }