int show_image(char *filename) { int (*load)(char *, unsigned char *, unsigned char **, int, int); unsigned char * image = NULL; unsigned char * alpha = NULL; int x_size, y_size, screen_width, screen_height; int x_pan, y_pan, x_offs, y_offs, refresh = 1, c, ret = 1; int delay = opt_delay, retransform = 1; int transform_stretch = opt_stretch, transform_enlarge = opt_enlarge, transform_cal = (opt_stretch == 2), transform_iaspect = opt_ignore_aspect, transform_rotation = 0; struct image i; #ifdef FBV_SUPPORT_GIF if(fh_gif_id(filename)) if(fh_gif_getsize(filename, &x_size, &y_size) == FH_ERROR_OK) { load = fh_gif_load; goto identified; } #endif #ifdef FBV_SUPPORT_PNG if(fh_png_id(filename)) if(fh_png_getsize(filename, &x_size, &y_size) == FH_ERROR_OK) { load = fh_png_load; goto identified; } #endif #ifdef FBV_SUPPORT_JPEG if(fh_jpeg_id(filename)) if(fh_jpeg_getsize(filename, &x_size, &y_size) == FH_ERROR_OK) { load = fh_jpeg_load; goto identified; } #endif #ifdef FBV_SUPPORT_BMP if(fh_bmp_id(filename)) if(fh_bmp_getsize(filename, &x_size, &y_size) == FH_ERROR_OK) { load = fh_bmp_load; goto identified; } #endif fprintf(stderr, "%s: Unable to access file or file format unknown.\n", filename); return(1); identified: if(!(image = (unsigned char*) malloc(x_size * y_size * 3))) { fprintf(stderr, "%s: Out of memory.\n", filename); goto error_mem; } if(load(filename, image, &alpha, x_size, y_size) != FH_ERROR_OK) { fprintf(stderr, "%s: Image data is corrupt?\n", filename); goto error_mem; } if(!opt_alpha) { free(alpha); alpha = NULL; } getCurrentRes(&screen_width, &screen_height); i.do_free = 0; while(1) { if(retransform) { if(i.do_free) { free(i.rgb); free(i.alpha); } i.width = x_size; i.height = y_size; i.rgb = image; i.alpha = alpha; i.do_free = 0; if(transform_rotation) do_rotate(&i, transform_rotation); if(transform_stretch) do_fit_to_screen(&i, screen_width, screen_height, transform_iaspect, transform_cal); if(transform_enlarge) do_enlarge(&i, screen_width, screen_height, transform_iaspect); x_pan = y_pan = 0; refresh = 1; retransform = 0; if(opt_clear) { printf("\033[H\033[J"); fflush(stdout); } if(opt_image_info) printf("fbv - The Framebuffer Viewer\n%s\n%d x %d\n", filename, x_size, y_size); } if(refresh) { if(i.width < screen_width) x_offs = (screen_width - i.width) / 2; else x_offs = 0; if(i.height < screen_height) y_offs = (screen_height - i.height) / 2; else y_offs = 0; fb_display(i.rgb, i.alpha, i.width, i.height, x_pan, y_pan, x_offs, y_offs); refresh = 0; } if(delay) { struct timeval tv; fd_set fds; tv.tv_sec = delay / 10; tv.tv_usec = (delay % 10) * 100000; FD_ZERO(&fds); FD_SET(0, &fds); if(select(1, &fds, NULL, NULL, &tv) <= 0) break; delay = 0; } c = getchar(); switch(c) { case EOF: case 'q': ret = 0; goto done; case ' ': case 10: case 13: goto done; case '>': case '.': goto done; case '<': case ',': ret = -1; goto done; case 'r': refresh = 1; break; case 'a': case 'D': if(x_pan == 0) break; x_pan -= i.width / PAN_STEPPING; if(x_pan < 0) x_pan = 0; refresh = 1; break; case 'd': case 'C': if(x_offs) break; if(x_pan >= (i.width - screen_width)) break; x_pan += i.width / PAN_STEPPING; if(x_pan > (i.width - screen_width)) x_pan = i.width - screen_width; refresh = 1; break; case 'w': case 'A': if(y_pan == 0) break; y_pan -= i.height / PAN_STEPPING; if(y_pan < 0) y_pan = 0; refresh = 1; break; case 'x': case 'B': if(y_offs) break; if(y_pan >= (i.height - screen_height)) break; y_pan += i.height / PAN_STEPPING; if(y_pan > (i.height - screen_height)) y_pan = i.height - screen_height; refresh = 1; break; case 'f': transform_stretch = !transform_stretch; retransform = 1; break; case 'e': transform_enlarge = !transform_enlarge; retransform = 1; break; case 'k': transform_cal = !transform_cal; retransform = 1; break; case 'i': transform_iaspect = !transform_iaspect; retransform = 1; break; case 'p': transform_cal = 0; transform_iaspect = 0; transform_enlarge = 0; transform_stretch = 0; retransform = 1; break; case 'n': transform_rotation -= 1; if(transform_rotation < 0) transform_rotation += 4; retransform = 1; break; case 'm': transform_rotation += 1; if(transform_rotation > 3) transform_rotation -= 4; retransform = 1; break; } } done: if(opt_clear) { printf("\033[H\033[J"); fflush(stdout); } error_mem: free(image); free(alpha); if(i.do_free) { free(i.rgb); free(i.alpha); } return(ret); }
int show_image(char *devicename) { unsigned char * image = NULL; unsigned char * alpha = NULL; int x_size, y_size, screen_width, screen_height; int x_pan, y_pan, x_offs, y_offs, refresh = 1, ret = 1; int retransform = 1; int transform_stretch = opt_stretch, transform_enlarge = opt_enlarge, transform_cal = (opt_stretch == 2), transform_iaspect = opt_ignore_aspect, transform_rotation = 0; struct image i; memset(&i,0, sizeof(i)); if(fh_png_load(&image, &alpha, &x_size, &y_size) != FH_ERROR_OK) { fprintf(stderr, "Image data is corrupt?\n"); goto error_mem; } if(!opt_alpha) { free(alpha); alpha = NULL; } getCurrentRes(devicename, &screen_width, &screen_height); i.do_free = 0; if(retransform) { if(i.do_free) { free(i.rgb); free(i.alpha); } i.width = x_size; i.height = y_size; i.rgb = image; i.alpha = alpha; i.do_free = 0; if(transform_rotation) do_rotate(&i, transform_rotation); if(transform_stretch) do_fit_to_screen(&i, screen_width, screen_height, transform_iaspect, transform_cal); if(transform_enlarge) do_enlarge(&i, screen_width, screen_height, transform_iaspect); x_pan = y_pan = 0; refresh = 1; retransform = 0; } if(refresh) { if(i.width < screen_width) x_offs = (screen_width - i.width) / 2; else x_offs = 0; if(i.height < screen_height) y_offs = (screen_height - i.height) / 2; else y_offs = 0; fb_display(devicename, i.rgb, i.alpha, i.width, i.height, x_pan, y_pan, x_offs, y_offs); refresh = 0; } error_mem: free(image); free(alpha); if(i.do_free) { free(i.rgb); free(i.alpha); } return(ret); }