Added own exif tag handling in files exif.[ch]
This commit is contained in:
		
							parent
							
								
									b752d5c594
								
							
						
					
					
						commit
						691c6d7e7e
					
				
							
								
								
									
										2
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								Makefile
									
									
									
									
									
								
							| @ -8,7 +8,7 @@ LIBS    = -lX11 -lImlib2 -lgif | |||||||
| PREFIX    = /usr/local | PREFIX    = /usr/local | ||||||
| MANPREFIX = $(PREFIX)/share/man | MANPREFIX = $(PREFIX)/share/man | ||||||
| 
 | 
 | ||||||
| SRC = commands.c image.c main.c options.c thumbs.c util.c window.c | SRC = commands.c exif.c image.c main.c options.c thumbs.c util.c window.c | ||||||
| OBJ = $(SRC:.c=.o) | OBJ = $(SRC:.c=.o) | ||||||
| 
 | 
 | ||||||
| all: options sxiv | all: options sxiv | ||||||
|  | |||||||
							
								
								
									
										131
									
								
								exif.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										131
									
								
								exif.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,131 @@ | |||||||
|  | /* sxiv: exif.c
 | ||||||
|  |  * Copyright (c) 2011 Bert Muennich <be.muennich at googlemail.com> | ||||||
|  |  * | ||||||
|  |  * This program is free software; you can redistribute it and/or modify it | ||||||
|  |  * under the terms of the GNU General Public License as published by the | ||||||
|  |  * Free Software Foundation; either version 2 of the License, or (at your | ||||||
|  |  * option) any later version. | ||||||
|  |  * | ||||||
|  |  * This program is distributed in the hope that it will be useful, but | ||||||
|  |  * WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||||
|  |  * General Public License for more details. | ||||||
|  |  * | ||||||
|  |  * You should have received a copy of the GNU General Public License along | ||||||
|  |  * with this program; if not, write to the Free Software Foundation, Inc., | ||||||
|  |  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #define _POSIX_C_SOURCE 200112L | ||||||
|  | 
 | ||||||
|  | #include <stdlib.h> | ||||||
|  | #include <fcntl.h> | ||||||
|  | #include <sys/stat.h> | ||||||
|  | #include <unistd.h> | ||||||
|  | 
 | ||||||
|  | #include "exif.h" | ||||||
|  | #include "util.h" | ||||||
|  | 
 | ||||||
|  | ssize_t s_read(int fd, const char *fn, void *buf, size_t n) { | ||||||
|  | 	ssize_t ret; | ||||||
|  | 
 | ||||||
|  | 	ret = read(fd, buf, n); | ||||||
|  | 	if (ret < n) { | ||||||
|  | 		warn("unexpected end-of-file: %s", fn); | ||||||
|  | 		return -1; | ||||||
|  | 	} else { | ||||||
|  | 		return ret; | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | unsigned short btous(unsigned char *buf, byteorder_t order) { | ||||||
|  | 	if (buf == NULL) | ||||||
|  | 		return 0; | ||||||
|  | 	if (order == BO_BIG_ENDIAN) | ||||||
|  | 		return buf[0] << 8 | buf[1]; | ||||||
|  | 	else | ||||||
|  | 		return buf[1] << 8 | buf[0]; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | unsigned int btoui(unsigned char *buf, byteorder_t order) { | ||||||
|  | 	if (buf == NULL) | ||||||
|  | 		return 0; | ||||||
|  | 	if (order == BO_BIG_ENDIAN) | ||||||
|  | 		return buf[0] << 24 | buf[1] << 16 | buf[2] << 8 | buf[3]; | ||||||
|  | 	else | ||||||
|  | 		return buf[3] << 24 | buf[2] << 16 | buf[1] << 8 | buf[0]; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | int exif_orientation(const fileinfo_t *file) { | ||||||
|  | 	int fd; | ||||||
|  | 	unsigned char data[EXIF_MAX_LEN]; | ||||||
|  | 	byteorder_t order = BO_BIG_ENDIAN; | ||||||
|  | 	unsigned int cnt, len, idx, val; | ||||||
|  | 
 | ||||||
|  | 	if (file == NULL || file->path == NULL) | ||||||
|  | 		return -1; | ||||||
|  | 
 | ||||||
|  | 	fd = open(file->path, O_RDONLY); | ||||||
|  | 	if (fd < 0) | ||||||
|  | 		return -1; | ||||||
|  | 
 | ||||||
|  | 	if (s_read(fd, file->name, data, 4) < 0) | ||||||
|  | 		goto abort; | ||||||
|  | 	if (btous(data, order) != JPEG_MARKER_SOI) | ||||||
|  | 		goto abort; | ||||||
|  | 	if (btous(data + 2, order) != JPEG_MARKER_APP1) | ||||||
|  | 		goto abort; | ||||||
|  | 
 | ||||||
|  | 	if (s_read(fd, file->name, data, 2) < 0) | ||||||
|  | 		goto abort; | ||||||
|  | 	len = btous(data, order); | ||||||
|  | 	if (len < 8) | ||||||
|  | 		goto abort; | ||||||
|  | 
 | ||||||
|  | 	if (s_read(fd, file->name, data, 6) < 0) | ||||||
|  | 		goto abort; | ||||||
|  | 	if (btoui(data, order) != EXIF_HEAD) | ||||||
|  | 		goto abort; | ||||||
|  | 
 | ||||||
|  | 	len -= 8; | ||||||
|  | 	if (len < 12 || len > EXIF_MAX_LEN) | ||||||
|  | 		goto abort; | ||||||
|  | 	if (s_read(fd, file->name, data, len) < 0) | ||||||
|  | 		goto abort; | ||||||
|  | 
 | ||||||
|  | 	switch (btous(data, order)) { | ||||||
|  | 		case EXIF_BO_BIG_ENDIAN: | ||||||
|  | 			order = BO_BIG_ENDIAN; | ||||||
|  | 			break; | ||||||
|  | 		case EXIF_BO_LITTLE_ENDIAN: | ||||||
|  | 			order = BO_LITTLE_ENDIAN; | ||||||
|  | 			break; | ||||||
|  | 		default: | ||||||
|  | 			goto abort; | ||||||
|  | 			break; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if (btous(data + 2, order) != EXIF_TAG_MARK) | ||||||
|  | 		goto abort; | ||||||
|  | 	idx = btoui(data + 4, order); | ||||||
|  | 	if (idx > len - 2) | ||||||
|  | 		goto abort; | ||||||
|  | 
 | ||||||
|  | 	val = 0; | ||||||
|  | 	cnt = btous(data + idx, order); | ||||||
|  | 
 | ||||||
|  | 	for (idx += 2; cnt > 0 && idx < len - 12; cnt--, idx += 12) { | ||||||
|  | 		if (btous(data + idx, order) == EXIF_TAG_ORIENTATION) { | ||||||
|  | 			val = btous(data + idx + 8, order); | ||||||
|  | 			printf("exif orientation: %s: %u\n", file->name, val); | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	close(fd); | ||||||
|  | 	return val; | ||||||
|  | 
 | ||||||
|  | abort: | ||||||
|  | 	close(fd); | ||||||
|  | 	return -1; | ||||||
|  | } | ||||||
							
								
								
									
										41
									
								
								exif.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								exif.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,41 @@ | |||||||
|  | /* sxiv: exif.h
 | ||||||
|  |  * Copyright (c) 2011 Bert Muennich <be.muennich at googlemail.com> | ||||||
|  |  * | ||||||
|  |  * This program is free software; you can redistribute it and/or modify it | ||||||
|  |  * under the terms of the GNU General Public License as published by the | ||||||
|  |  * Free Software Foundation; either version 2 of the License, or (at your | ||||||
|  |  * option) any later version. | ||||||
|  |  * | ||||||
|  |  * This program is distributed in the hope that it will be useful, but | ||||||
|  |  * WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||||
|  |  * General Public License for more details. | ||||||
|  |  * | ||||||
|  |  * You should have received a copy of the GNU General Public License along | ||||||
|  |  * with this program; if not, write to the Free Software Foundation, Inc., | ||||||
|  |  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #ifndef EXIF_H | ||||||
|  | #define EXIF_H | ||||||
|  | 
 | ||||||
|  | #include "types.h" | ||||||
|  | 
 | ||||||
|  | enum { | ||||||
|  | 	JPEG_MARKER_SOI  = 0xFFD8, | ||||||
|  | 	JPEG_MARKER_APP1 = 0xFFE1 | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | enum { | ||||||
|  | 	EXIF_MAX_LEN          = 0x10000, | ||||||
|  | 	EXIF_HEAD             = 0x45786966, | ||||||
|  | 	EXIF_BO_BIG_ENDIAN    = 0x4D4D, | ||||||
|  | 	EXIF_BO_LITTLE_ENDIAN = 0x4949, | ||||||
|  | 	EXIF_TAG_MARK         = 0x002A, | ||||||
|  | 	EXIF_TAG_ORIENTATION  = 0x0112 | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | int exif_orientation(const fileinfo_t*); | ||||||
|  | void exif_auto_orientate(const fileinfo_t*); /* in image.c */ | ||||||
|  | 
 | ||||||
|  | #endif /* EXIF_H */ | ||||||
							
								
								
									
										31
									
								
								image.c
									
									
									
									
									
								
							
							
						
						
									
										31
									
								
								image.c
									
									
									
									
									
								
							| @ -25,6 +25,7 @@ | |||||||
| #include <unistd.h> | #include <unistd.h> | ||||||
| #include <gif_lib.h> | #include <gif_lib.h> | ||||||
| 
 | 
 | ||||||
|  | #include "exif.h" | ||||||
| #include "image.h" | #include "image.h" | ||||||
| #include "options.h" | #include "options.h" | ||||||
| #include "util.h" | #include "util.h" | ||||||
| @ -64,6 +65,34 @@ void img_init(img_t *img, win_t *win) { | |||||||
| 	img->multi.animate = false; | 	img->multi.animate = false; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void exif_auto_orientate(const fileinfo_t *file) { | ||||||
|  | 	switch (exif_orientation(file)) { | ||||||
|  | 		case 5: | ||||||
|  | 			imlib_image_orientate(1); | ||||||
|  | 		case 2: | ||||||
|  | 			imlib_image_flip_vertical(); | ||||||
|  | 			break; | ||||||
|  | 
 | ||||||
|  | 		case 3: | ||||||
|  | 			imlib_image_orientate(2); | ||||||
|  | 			break; | ||||||
|  | 
 | ||||||
|  | 		case 7: | ||||||
|  | 			imlib_image_orientate(1); | ||||||
|  | 		case 4: | ||||||
|  | 			imlib_image_flip_horizontal(); | ||||||
|  | 			break; | ||||||
|  | 
 | ||||||
|  | 		case 6: | ||||||
|  | 			imlib_image_orientate(1); | ||||||
|  | 			break; | ||||||
|  | 
 | ||||||
|  | 		case 8: | ||||||
|  | 			imlib_image_orientate(3); | ||||||
|  | 			break; | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
| bool img_load_gif(img_t *img, const fileinfo_t *file) { | bool img_load_gif(img_t *img, const fileinfo_t *file) { | ||||||
| 	GifFileType *gif; | 	GifFileType *gif; | ||||||
| 	GifRowType *rows = NULL; | 	GifRowType *rows = NULL; | ||||||
| @ -254,6 +283,8 @@ bool img_load(img_t *img, const fileinfo_t *file) { | |||||||
| 		warn("could not open image: %s", file->name); | 		warn("could not open image: %s", file->name); | ||||||
| 		return false; | 		return false; | ||||||
| 	} | 	} | ||||||
|  | 	if (STREQ(fmt, "jpeg")) | ||||||
|  | 		exif_auto_orientate(file); | ||||||
| 	if (STREQ(fmt, "gif")) | 	if (STREQ(fmt, "gif")) | ||||||
| 		img_load_gif(img, file); | 		img_load_gif(img, file); | ||||||
| 
 | 
 | ||||||
|  | |||||||
							
								
								
									
										3
									
								
								thumbs.c
									
									
									
									
									
								
							
							
						
						
									
										3
									
								
								thumbs.c
									
									
									
									
									
								
							| @ -26,6 +26,7 @@ | |||||||
| #include <unistd.h> | #include <unistd.h> | ||||||
| #include <utime.h> | #include <utime.h> | ||||||
| 
 | 
 | ||||||
|  | #include "exif.h" | ||||||
| #include "thumbs.h" | #include "thumbs.h" | ||||||
| #include "util.h" | #include "util.h" | ||||||
| #include "config.h" | #include "config.h" | ||||||
| @ -254,6 +255,8 @@ bool tns_load(tns_t *tns, int n, const fileinfo_t *file, | |||||||
| 		imlib_free_image_and_decache(); | 		imlib_free_image_and_decache(); | ||||||
| 		return false; | 		return false; | ||||||
| 	} | 	} | ||||||
|  | 	if (STREQ(fmt, "jpeg")) | ||||||
|  | 		exif_auto_orientate(file); | ||||||
| 
 | 
 | ||||||
| 	w = imlib_image_get_width(); | 	w = imlib_image_get_width(); | ||||||
| 	h = imlib_image_get_height(); | 	h = imlib_image_get_height(); | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Bert Münnich
						Bert Münnich