Mercurial > geeqie
diff src/format_raw.c @ 45:7cfa60beda76
Thu May 26 13:57:19 2005 John Ellis <johne@verizon.net>
* format_raw.[ch]: Move camera specific code to manufacturer specific
format_*.c files. Change code so that file descripter version is now a
separate functions that wraps the standard parser by using mmap.
* format_canon.[ch]: Moved Canon specific raw support here, removed
file descriptor versions of parser. This Canon raw file parser written
by Daniel M. German.
* format_fuji.[ch]: Move Fuji specific raw support here, parser written
by Lars Ellenberg.
* exif.c: Update for change to format_raw_img_exif_offsets.
* filelist.c: Add cr2 extension to Canon raw format list.
* image-load.c: Fixes for changes to format_raw_img_exif_offset_fd so
that buffer is refilled using new offset of file descriptor.
* src/Makefile.am: Add format_canon.[ch], format_fuji.[ch] to build.
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
##### an offical release when making enhancements and translation updates. #####
author | gqview |
---|---|
date | Thu, 26 May 2005 18:10:52 +0000 |
parents | ee03f36e9e4b |
children | 905f8fa583a3 |
line wrap: on
line diff
--- a/src/format_raw.c Wed May 18 23:52:16 2005 +0000 +++ b/src/format_raw.c Thu May 26 18:10:52 2005 +0000 @@ -14,9 +14,13 @@ # include "config.h" #endif + #include <stdio.h> #include <string.h> #include <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/mman.h> #include <glib.h> @@ -24,54 +28,59 @@ #include "format_raw.h" -static gint format_raw_test_canon(int fd, const void *data, const guint len, - guint *image_offset, guint *exif_offset) -{ - return FALSE; -} +#include "format_canon.h" +#include "format_fuji.h" + + +typedef struct _FormatEntry FormatEntry; +struct _FormatEntry { + const void *header_pattern; + const guint header_length; + const gchar *description; + FormatRawParseFunc func_parse; +}; + -static gint format_raw_test_fuji(int fd, const void *data, const guint len, - guint *image_offset, guint *exif_offset) +static FormatEntry format_list[] = { + FORMAT_RAW_CANON, + FORMAT_RAW_FUJI, + { NULL, 0, NULL, NULL } +}; + + +static FormatEntry *format_raw_find(const void *data, const guint len) { - if (len < 128 || - memcmp(data, "FUJIFILM", 8) != 0) + gint n; + + n = 0; + while (format_list[n].header_pattern) { - return FALSE; + if (format_list[n].header_length <= len && + memcmp(data, format_list[n].header_pattern, format_list[n].header_length) == 0) + { + return &format_list[n]; + } + n++; } - *image_offset = GUINT32_FROM_BE(*(guint32*)(data + 84)); - *exif_offset = *image_offset + 12; -printf("found a raw fuji file!\n"); - return TRUE; + return NULL; } -static gint format_raw_test_nikon(int fd, const void *data, const guint len, - guint *image_offset, guint *exif_offset) +static gint format_raw_parse(FormatEntry *entry, + const void *data, const guint len, + guint *image_offset, guint *exif_offset) { - return FALSE; -} - - -gint format_raw_img_exif_offsets(int fd, const void *data, const guint len, - guint *image_offset, guint *exif_offset) -{ - guint32 io = 0; - guint32 eo = 0; + gint io = 0; + gint eo = 0; gint found; - if (fd < 0 && !data) return FALSE; -#if 0 - if (len < 512) return FALSE; -#endif + if (!entry || !entry->func_parse) return FALSE; - found = format_raw_test_canon(fd, data, len, &io, &eo) || - format_raw_test_fuji (fd, data, len, &io, &eo) || - format_raw_test_nikon(fd, data, len, &io, &eo); + found = entry->func_parse(data, len, &io, &eo); if (!found || io >= len - 4 || - eo >= len || - memcmp(data + io, "\xff\xd8\xff\xe1", 4) != 0) /* jpeg marker */ + eo >= len) { return FALSE; } @@ -82,5 +91,69 @@ return TRUE; } +gint format_raw_img_exif_offsets(const void *data, const guint len, + guint *image_offset, guint *exif_offset) +{ + FormatEntry *entry; + + if (!data || len < 1) return FALSE; + + entry = format_raw_find(data, len); + + if (!entry || !entry->func_parse) return FALSE; + + return format_raw_parse(entry, data, len, image_offset, exif_offset); +} +gint format_raw_img_exif_offsets_fd(int fd, const void *header_data, const guint header_len, + guint *image_offset, guint *exif_offset) +{ + FormatEntry *entry; + void *map_data = NULL; + size_t map_len = 0; + struct stat st; + gint success; + + if (!header_data || fd < 0) return FALSE; + + entry = format_raw_find(header_data, header_len); + + if (!entry || !entry->func_parse) return FALSE; + + if (fstat(fd, &st) == -1) + { + printf("Failed to stat file %d\n", fd); + return FALSE; + } + map_len = st.st_size; + map_data = mmap(0, map_len, PROT_READ, MAP_PRIVATE, fd, 0); + if (map_data == MAP_FAILED) + { + printf("Failed to mmap of file %d\n", fd); + return FALSE; + } + + success = format_raw_parse(entry, map_data, map_len, image_offset, exif_offset); + + if (munmap(map_data, map_len) == -1) + { + printf("Failed to unmap file %d\n", fd); + } + + if (success && image_offset) + { + if (lseek(fd, *image_offset, SEEK_SET) != *image_offset) + { + printf("Failed to seek to embedded image\n"); + + *image_offset = 0; + if (*exif_offset) *exif_offset = 0; + success = FALSE; + } + } + + return success; +} + +