Mercurial > geeqie
changeset 1010:82fe98d2cfdb
added new raw preview interface for legacy exif
author | nadvornik |
---|---|
date | Fri, 29 Aug 2008 09:59:20 +0000 |
parents | dd311dae857a |
children | 616b14da08c2 |
files | src/exif-int.h src/exif.c |
diffstat | 2 files changed, 87 insertions(+), 1 deletions(-) [+] |
line wrap: on
line diff
--- a/src/exif-int.h Fri Aug 29 09:38:10 2008 +0000 +++ b/src/exif-int.h Fri Aug 29 09:59:20 2008 +0000 @@ -64,6 +64,7 @@ struct _ExifData { + gchar *path; GList *items; /* list of (ExifItem *) */ GList *current; /* for exif_get_next_item */ };
--- a/src/exif.c Fri Aug 29 09:38:10 2008 +0000 +++ b/src/exif.c Fri Aug 29 09:59:20 2008 +0000 @@ -1158,6 +1158,7 @@ } g_list_free(exif->items); + g_free(exif->path); g_free(exif); } @@ -1181,6 +1182,7 @@ exif = g_new0(ExifData, 1); exif->items = NULL; exif->current = NULL; + exif->path = g_strdup(path); res = exif_jpeg_parse(exif, (guchar *)f, size, ExifKnownMarkersList); if (res == -2) @@ -1305,7 +1307,7 @@ } else { - val = (guchar)(((signed gchar *)data)[0]); + val = (guchar)(((gchar *)data)[0]); } result = exif_text_list_find_value(marker->list, (guint)val); @@ -1543,6 +1545,89 @@ } +typedef struct _UnmapData UnmapData; +struct _UnmapData +{ + guchar *ptr; + guchar *map_data; + size_t map_len; +}; + +static GList *exif_unmap_list = 0; + +guchar *exif_get_preview(ExifData *exif, guint *data_len) +{ + int success; + guint offset; + const gchar* path; + struct stat st; + guchar *map_data; + size_t map_len; + int fd; + + if (!exif) return NULL; + path = exif->path; + + fd = open(path, O_RDONLY); + + + if (fd == -1) + { + return 0; + } + + if (fstat(fd, &st) == -1) + { + close(fd); + return 0; + } + map_len = st.st_size; + map_data = (guchar *) mmap(0, map_len, PROT_READ, MAP_PRIVATE, fd, 0); + close(fd); + + if (map_data == MAP_FAILED) + { + return 0; + } + + if (format_raw_img_exif_offsets(map_data, map_len, &offset, NULL) && offset) + { + UnmapData *ud; + + DEBUG_1("%s: offset %lu", path, offset); + + *data_len = map_len - offset; + ud = g_new(UnmapData, 1); + ud->ptr = map_data + offset; + ud->map_data = map_data; + ud->map_len = map_len; + + exif_unmap_list = g_list_prepend(exif_unmap_list, ud); + return ud->ptr; + } + + munmap(map_data, map_len); + return NULL; + +} + +void exif_free_preview(guchar *buf) +{ + GList *work = exif_unmap_list; + + while (work) + { + UnmapData *ud = (UnmapData *)work->data; + if (ud->ptr == buf) + { + exif_unmap_list = g_list_remove_link(exif_unmap_list, work); + g_free(ud); + return; + } + } + g_assert_not_reached(); +} + #endif /* not HAVE_EXIV2 */