Based on wrlib EXIF orientation feature, this patch is adding orientation detection and provides 2 more shortcuts for live right/left rotation. Internal version was increased to 0.7.
--- util/wmiv.c | 103 +++++++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 89 insertions(+), 14 deletions(-) diff --git a/util/wmiv.c b/util/wmiv.c index 2eab5d3..92032f2 100755 --- a/util/wmiv.c +++ b/util/wmiv.c @@ -57,7 +57,7 @@ Pixmap pix; const char *APPNAME = "wmiv"; int APPVERSION_MAJOR = 0; -int APPVERSION_MINOR = 6; +int APPVERSION_MINOR = 7; int NEXT = 0; int PREV = 1; float zoom_factor = 0; @@ -66,6 +66,7 @@ int max_height = 0; Bool fullscreen_flag = False; Bool focus = False; +Bool back_from_fullscreen = False; #ifdef HAVE_PTHREAD Bool diaporama_flag = False; @@ -212,6 +213,59 @@ int merge_with_background(RImage *i) } /* + turn_image: rotate the image by the angle passed + return EXIT_SUCCESS on success, EXIT_FAILURE on failure +*/ +int turn_image(float angle) +{ + RImage *tmp; + + if (!img) + return EXIT_FAILURE; + + tmp = RRotateImage(img, angle); + if (!tmp) + return EXIT_FAILURE; + + if (!fullscreen_flag) { + if (img->width != tmp->width || img->height != tmp->height) + XResizeWindow(dpy, win, tmp->width, tmp->height); + } + + RReleaseImage(img); + img = tmp; + + rescale_image(); + if (!fullscreen_flag) { + XCopyArea(dpy, pix, win, ctx->copy_gc, 0, 0, img->width, img->height, 0, 0); + } else { + XClearWindow(dpy, win); + XCopyArea(dpy, pix, win, ctx->copy_gc, 0, 0, + img->width, img->height, max_width/2-img->width/2, max_height/2-img->height/2); + } + + return EXIT_SUCCESS; +} + +/* + turn_image_right: rotate the image by 90 degree + return EXIT_SUCCESS on success, EXIT_FAILURE on failure +*/ +int turn_image_right(void) +{ + return turn_image(90.0); +} + +/* + turn_image_left: rotate the image by -90 degree + return EXIT_SUCCESS on success, 1 on failure +*/ +int turn_image_left(void) +{ + return turn_image(-90.0); +} + +/* draw_failed_image: create a red crossed image to indicate an error loading file return the image on success, NULL on failure @@ -250,6 +304,7 @@ int full_screen(void) if (fullscreen_flag) { fullscreen_flag = False; zoom_factor = 0; + back_from_fullscreen = True; } else { fullscreen_flag = True; zoom_factor = 1000; @@ -279,7 +334,7 @@ int full_screen(void) int zoom_in_out(int z) { RImage *old_img = img; - RImage *tmp = RLoadImage(ctx, current_link->data, 0); + RImage *tmp = RLoadOrientedImage(ctx, current_link->data, 0); if (!tmp) return EXIT_FAILURE; @@ -368,7 +423,7 @@ int change_image(int way) } if (DEBUG) fprintf(stderr, "current file is> %s\n", (char *)current_link->data); - img = RLoadImage(ctx, current_link->data, 0); + img = RLoadOrientedImage(ctx, current_link->data, 0); if (!img) { fprintf(stderr, "Error: %s %s\n", (char *)current_link->data, @@ -453,7 +508,7 @@ int linked_list_add(linked_list_t *list, const void *data) /* calloc sets the "next" field to zero. */ link = calloc(1, sizeof(link_t)); if (!link) { - fprintf(stderr, "calloc failed.\n"); + fprintf(stderr, "Error: memory allocation failed\n"); return EXIT_FAILURE; } link->data = data; @@ -572,7 +627,9 @@ int main(int argc, char **argv) #ifdef HAVE_PTHREAD "d: launch diaporama mode\n" #endif + "l: rotate image on the left\n" "q: quit\n" + "r: rotate image on the right\n" "right: next image\n" "left: previous image\n" "up: first image\n" @@ -618,7 +675,7 @@ int main(int argc, char **argv) } } - img = RLoadImage(ctx, reading_filename, 0); + img = RLoadOrientedImage(ctx, reading_filename, 0); if (!img) { fprintf(stderr, "Error: %s %s\n", reading_filename, RMessageForError(RErrorCode)); @@ -703,21 +760,33 @@ int main(int argc, char **argv) XConfigureEvent xce = e.xconfigure; if (xce.width != img->width || xce.height != img->height) { RImage *old_img = img; - img = RLoadImage(ctx, current_link->data, 0); + img = RLoadOrientedImage(ctx, current_link->data, 0); if (!img) { /* keep the old img and window size */ img = old_img; XResizeWindow(dpy, win, img->width, img->height); } else { - img = RScaleImage(img, xce.width, xce.height); - if (!img) { - img = old_img; - XResizeWindow(dpy, win, img->width, img->height); - } else { - merge_with_background(img); - if (RConvertImage(ctx, img, &pix)) - RReleaseImage(old_img); + RImage *tmp2; + if (!back_from_fullscreen) + /* manually resized window */ + tmp2 = RScaleImage(img, xce.width, xce.height); + else { + /* back from fullscreen mode, maybe img was rotated */ + tmp2 = img; + back_from_fullscreen = False; + XClearWindow(dpy, win); + } + merge_with_background(tmp2); + if (RConvertImage(ctx, tmp2, &pix)) { + RReleaseImage(old_img); + img = RCloneImage(tmp2); + RReleaseImage(tmp2); + change_title(&title_property, (char *)current_link->data); + XSync(dpy, True); XResizeWindow(dpy, win, img->width, img->height); + XCopyArea(dpy, pix, win, ctx->copy_gc, 0, 0, + img->width, img->height, 0, 0); + } } } @@ -814,6 +883,12 @@ int main(int argc, char **argv) case XK_f: full_screen(); break; + case XK_r: + turn_image_right(); + break; + case XK_l: + turn_image_left(); + break; } } -- 1.8.3.2
0002-util-wmiv-add-image-auto-orientation-detection.patch
Description: Binary data